Eu tenho estudado o pagamento do código QR de Alipay há algum tempo. Devo dizer que o documento de Alipay é realmente ruim (pelo menos foi de Mengbi quando eu o li pela primeira vez). Os exemplos acima do documento parecem completamente diferentes dos exemplos na demonstração. Muitas vezes, os exemplos acima do documento são muito simples, enquanto o código de demonstração é muito complicado, então eu não sabia qual código usar no início. Mais tarde, olhei cuidadosamente para o código no pacote de demonstração e descobri que as interfaces dos exemplos de documentos também foram chamadas. Só então eu percebi que eles eram a mesma coisa, mas a demonstração apenas envolveu as interfaces do documento.
Primeiro, solicite uma conta da Alipay de uma empresa. Esta conta possui um PID e você precisa adicionar um aplicativo a esta conta. Cada aplicativo possui um Appid e uma chave pública e privada. As chaves públicas e privadas podem ser geradas através de ferramentas fornecidas pela Alipay. Além disso, os desenvolvedores Java precisam usar chaves privadas no formato PKCS6. Se o aplicativo precisar usar a função de digitalização, será necessário adicionar a opção de pagamento pessoal no aplicativo, o que requer assinar um contrato. Depois de assinar a função de pagamento pessoalmente, ela não pode ser usada diretamente porque o aplicativo precisa estar online antes que possa ser usado. Portanto, você pode usar a versão Sandbox do aplicativo durante o desenvolvimento. Alipay fornece a versão Sandbox do gateway, Alipay Public Key, PID e Appid, que precisam ser modificados durante a configuração.
O código pode usar diretamente o código na demonstração, primeiro importar a API fornecida por Alipay no projeto (observe que não é o código de demonstração) e depois importar o código de demonstração, como mostrado na figura:
Este arquivo com.alipay.demo.trade.main pode ser executado diretamente, mas um arquivo de recursos precisa ser configurado:
# Alipay Gateway Nome, PartnerID e Appid# Este é o gateway para o ambiente da Sandbox Open_Api_Domain = https://openapi.alipaydev.com/gateway.domcloud_api_domain = http://mcloudmonitor.com/gateway.do isto é o mecâncias No AppidAppid para o seu ambiente de sandbox pessoalmente aqui = 2016082000300485 # RSA Chave privada, chave pública e chave pública Alipay #, por favor, preencha sua chave privada do comerciante aqui e transfira para PKCS8 formato privado_key = Miiceqibadanbgkqhkig9w0baqefaScammwggjfageaaogbamkxzrfr+rnvygbs9qz2ce1mcsibereaqan+5pf5+02hyj4hzcnttwqhfm91ih 3wypyhpm7xlbgj5ywjtgc4g1lz75r8a+ucyuxp8by1lv/44gi/tiflsgatfq73ocm9Imxocrdyz2ZCWQi1GV+B3Udoy/da5W07GrWizfzs6VQ 1RAGMBAAECGYAQHHC4GRBSRCKINYTK1VHQCJ0YG11LVY85Z3SI0FNY26DVS8R5GFYDZC/MX5F8RNPUUYUHQN+4CQOR3D/CO291X1ITOV2NEV Lhejroudknp4Oqriqt2w9pz8rzwzp2jcwvrvUf4ztpeimppmorp6sprfx6dlzg29sfi6gzwu6tkcqdp3mim1bhus3yonezgqc69z0/dgofk EIX0S18qau1x4i1fejvtky4hpdwiHpgyajm0Ufg1lk8mtiunHpzrcnakea1qf6u1akjm6zsvdenrxedtc75uvjgsyfjwhx9pjyd9vx8nszv 0Z0U4V0ZG0N0YVHJ5LRO6U5FCQFRW1WIXNQJBALMCKZ8SVF/H9N6LIWMSPY6W5Q82KNRLRC7WSCENSPQT0WQL5+SACG98M0XXY5J1HMIONHXG CtvyRIXOWOBIVQCCQCTNANB4UZ3Q/86R/KUKBVD3DIRWLFRYAHO6YXP8OY+JE/BV/359+VR3CXZYYLDHZOR9/TVSPWR/Y9Q4JLEM Q1TAKEALBU7+4EDZFAP7E/FMGYKD5DML8H2IAEUMRRCPL84GHFFK/7PSQ/40NGKXPTGY44NLHXCRPW5CZU6GQDINJOA ==#Por favor Preencha seu comerciante public_key aqui = MigfMA0GCSQGSIBDQEBAQUA4GNADCBIQKBGQDCL2AXUFQ572iABPAS9NBNZGKIAUXMQMP/UT3+FTNH8O+B83DU01QHXZVDSB98GD8ATO15W Ceclibyauinzc ++ a/gvlasrst/g8ts1f+obov0yhy0oae30O9zndpypl6hexwm9mqskotyffm91a6mvw2ucno4evosxc0ulatawidaqab# é a chave pública do ambiente de sandbox alipay_public_key = MigfMA0GCSQGSIB3DQEBAQUAA4GNADCBIQKBGQDIGHNON7LILLKKETD6BFRJ0GQGS2Y3MN1WMQMYH9ZEYWLZ5P1ZRAHRAHBXAFCFSQSHSNFQ OMAQZSHRVJCQJSAW1JYQRXAPDKBMR90DIPIXMIYKXV4GGAKPYJ/6FTFY99UHPIQ0QADD/USZQSEFWO0ATVP/65ZI3EOF7TCZ32OWPWIDAQAB# Número máximo de consultas e intervalo de consulta (milissegundos) max_query_retry = 5query_duration = 5000# Número máximo de desvantagens e intervalos de desfazer (ms) em pessoa max_cancel_rettry = 3Cancel_Djation = 2000# THREAGEM DE TRANSACTIONETRATELTUMENTETBETBRY = 3Cancel_Djation = 2000# Garantia de transação.
Em seguida, execute o arquivo main.java. Quanto ao código de pagamento para o código de digitalização em nosso aplicativo real, podemos copiar diretamente a função test_trade_precreate () no arquivo main.java e criar uma função no controlador:
@RequestMapping (Value = "/Pay/Alipay", Method = RequestMethod.Post) Map public <String, String> Alipay (@RequestParam String Montante, @RequestParam int UserID) {map <String, String> map = new Hashmap <String, String> (); // (requerido) O número de pedido exclusivo no sistema de pedidos de sites do comerciante, com apenas 64 caracteres, pode conter apenas letras, números e sublinhados. // É necessário garantir que o sistema do comerciante não possa ser repetido. Recomenda -se gerá -lo através da sequência do banco de dados, String outtradeno = "xxxxx" + System.currenttimemillis () + (long) (math.random () * 10000000l); // (requerido) O título do pedido descreve aproximadamente o objetivo de pagamento do usuário. Por exemplo, "XXX Brand XXX Store paga pessoalmente e digitaliza o código para consumir" String sujeito = "Pay"; // (exigido) O valor total do pedido é de RMB 100 milhões e não pode exceder RMB 100 milhões // se [valor descontado], [não descontado] e [o valor total da ordem] são transmitidos ao mesmo tempo, as seguintes condições devem ser atendidas: [valor total da ordem] = [valor descontado] + [não desconto] string) // (opcional) O pedido não pode ser descontado e pode ser configurado com a plataforma do comerciante para configurar atividades de desconto. Se o álcool não participar do desconto, o valor correspondente será preenchido nesse campo // se o valor não for transmitido, mas [o valor total da ordem] e o valor do [desconto] serão transmitidos, o valor padrão para [valor total da ordem]-[valor descontado] string não discordamountount = "0"; // O ID da conta do Alipay do vendedor é usado para apoiar o pagamento a diferentes contas de pagamento em uma conta do contrato (pague à conta de Alipay correspondente ao SellerID) // Se esse campo estiver vazio, ele padroniza o PID do comerciante assinado com Alipay, ou seja, o PID correspondente ao String Appid String = "208102172220 // Descrição do pedido, você pode descrever a transação ou produto de maneira detalhada, como preencher "2 compras de 2 itens no total de 15,00 yuan" String body = "3 compras de 3 itens no total 20,00 yuan"; // Número do operador do comerciante, adicione este parâmetro para fazer estatísticas de vendas para o operador de comerciante operador operatorId = "test_operator_id"; // (necessário) Número da loja do comerciante, através do número da loja e do back -end do comerciante, você pode configurar as informações de desconto para a loja com precisão. Para detalhes, consulte o Alipay Technical Support String StoreID = "2088102172329883"; // Parâmetros de expansão de negócios, atualmente você pode adicionar o número do provedor do sistema atribuído por Alipay (através do método SetSySerServiceProviderid). Para detalhes, consulte o suporte técnico do Alipay ExtendParams ExtendParams = new ExtendParams (); ExtendParams.setsySerServiceProviderId ("2088100200300400500"); // Tempo limite de pagamento, definido como 120 minutos de string timeoutExpress = timeout; // // Lista de detalhes do produto, você precisa preencher os detalhes do produto de compra, // LIST <SGERSDETAIL> bensDetaillist = New ArrayList <GoodsDetail> (); // // Criar informações do produto, os parâmetros são os parâmetros e o preço do produto (uso nacional). Se você precisar adicionar categorias de produtos, consulte BODSDETAIL // BOTSDETAIL BOTS1 = BOTSDETAIL.NEWINSTANCE ("BOODS_ID001", "XXX Pequeno pão", 1000, 1); // // Adicionar à lista de detalhes do produto para criar um produto // bensdetAillist.add (bens1); O produto comprado pelo usuário é "escova de dentes preto", com um preço unitário de 5,00 yuan. Comprei duas peças // bensDetail bens2 = bensDetail.newinstance ("bens_id002", "xxx dentes de dentes", 500, 2); // bensdetaillist.add (bens2); // Crie um código de varredura para pagar o construtor de solicitações, defina os parâmetros de solicitação AlipayTradePreteaterEquestBuilder Builder = new AlipaytradeRePreaterEquestBuilder () .SetSubject (sujeito) .SetTOLAMount (TotalAmount) .SelEArtSliStIntSountSountIntEnSountIntEnTount (Outtradeno) .SeltUndSlountountount (total). .setbody (body) .setOperatorId (operatorId) .setStoreid (storeID) .SetextendParams (ExtendParams) .SetTimeOutExpress (timeoutExpress) .setNotifyurl ("http://xxx.xx.xxxxxxxx:8080/baobiaoo-pay/xxx.xx.xxxxxxxx:8080/baobiao-pay/nynyny/niPy/niPy/niPy/niPay/niPy/niPy/niFiSty/niFIMIFIMIFIMENTO/ALMIPAY/PAY/NIPAY/NIPAY/NIMIFE" Caminho HTTP especificado no servidor de comerciantes. Definido conforme necessário. Aqui, definimos uma interface que escrevemos para nós mesmos. Vamos apresentá -lo mais tarde. // .setgoodsdetaillist (bensdetaillist); ALIPAYF2FPRECREATEResult resultado = tradeService.tradeprecreate (construtor); switch (resultado.getTradeStatus ()) {sucessão do caso: log.info ("Alipay pré-encomendou com sucesso :)"); System.out.println ("Alipay pré-encomendou com sucesso :)"); AlipaytradePrecReaterSponse Response = resultado.GetResponse (); // DumProSponse (Response); // System.out.println (Response.getBody ()); // // //, ele precisa ser modificado no caminho na máquina de corrida // string filepath.format ("/users log.info ("filepath:" + filepath); // zxingutils.getqrcodeImge (Response.getqrcode (), 256, filepath); // System.out.println (Respons.getqrcode ()); // Gere um pedido e insira o banco de dados Baobiaoorder Order = New Baobiaoorder (UserID, Outtradeno, "", Double.parsedouble (quantidade), new Date (), 1); BaobiaoorderService.insertOrder (Ordem); map.put ("status", "true"); map.put ("qrcode", Response.getqrcode ()); // retorna ao Código QR do cliente Map.put ("Outtradeno", Outtradeno); mapa de retorno; Falha no caso: log.error ("Alipay pré-encomenda falhou !!!"); System.out.println ("ALIPAY PROMEDA FALHADO !!!"); System.out.println (resultado.getResponse (). GetBody ()); quebrar; Caso desconhecido: log.error ("Exceção do sistema, status de pré-venda desconhecido !!!"); System.out.println ("Exceção do sistema, status de pré-venda desconhecido !!!"); quebrar; padrão: log.error ("status da transação não suportada, transação retorna exceção !!!"); System.out.println ("Status da transação não suportada, Exceção de retorna da transação !!!"); quebrar; } map.put ("status", "false"); map.put ("msg", "o sistema tem uma exceção, tente novamente mais tarde!"); mapa de retorno; }A lógica é que o usuário digitalizará o código em seu telefone celular para pagar a Alipay e, depois que Alipay o receber, ele enviará uma mensagem de pagamento bem -sucedido para definir notify_url, como mostrado abaixo:
@RequestMapping (value = "/pay/notify", métod = requestMethod.post) public string notifyResult (solicitação httpServletRequest, httpServletResponse resposta) {log.info ("Notificação assíncrona de Alipay recebeu!"); Mapa <string, string> params = new hashmap <string, string> (); // Recuperar todos os parâmetros para verificar a enumeração de assinatura <String> parameterNames = request.getParameterNames (); while (parameterNames.hasMoreElements ()) {string parameterName = parameterNames.nextElement (); params.put (nome do parametern, request.getParameter (parameterName)); } significado booleano; tente {signVerified = alipaySignature.rsacheckv1 (params, configs.getalipaypublickey (), "utf-8"); } catch (alipayapiexception e) {e.printStackTrace (); retornar "falhou"; } if (SignVerificado) {String outtradeno = params.get ("out_trade_no"); Log.info (Outtradeno + "Notificação de retorno de chamada do pedido."); // System.out.println ("Verifique a assinatura com sucesso!"); log.info ("Verifique a assinatura com sucesso!"); // Se o Appid no parâmetro for diferente do Appid preenchido, é uma notificação de exceção se (! Configs.getAppid (). Iguals (params.get ("app_id"))) {Log.warn ("diferente do Appid no momento do pagamento, esta é uma notificação de exceção e deve ser ignorada!"); retornar "falhou"; } // Encontre o pedido correspondente ao número do pedido no banco de dados e compare seu valor com o valor no banco de dados. Se não corresponder, também notificará a exceção do Baobiaoorder Order = BaobiaoorderService.FindOrderByoutTradeno (Outtradeno); if (ordem == null) {log.warn (outtradeno + "verifique este pedido sem verificar!"); retornar "falhou"; } if (order.getamount ()! = Double.parseDouble (params.get ("total_amount"))) {log.warn ("diferente do valor no momento do pagamento, esta é uma notificação de exceção e deve ser ignorada!"); retornar "falhou"; } if (order.getStatus () == Baobiaoorder.trade_success) retorna "Sucesso"; // Se o pedido tiver sido pago com sucesso, ignore esta string de notificação status = params.get ("trade_status"); if (status.equals ("wait_buyer_pay")) {// se o status estiver aguardando o pagamento do usuário se (order.getStatus ()! = Baobiaoorder.wait_buyer_pay) baobiaoorderService.modifytradestatus (baobiaorder.ways_buyer_puyer_puyer_puyer_puyer_puyer_puyerceer.puyerd.modifytratestatus (baobiaoorder.ways_buyer_buyer_puyer_puyer_puyer_payer; } else if (status.equals ("trade_closed")) {// se o status não for pago no tempo limite da transação, ou o pagamento for totalmente reembolsado se (order.getStatus ()! = baobiaoorder.trade_closed) baobiaoorderService.modifytadeNoSTusus (Baobiaoudder.Letadeder.Closed.Closed) } else if (status.equals ("trade_success") || status.equals ("trade_finished")) {// se o status for pago com sucesso se (order.getStatus ()! } else {BaobiaoorderService.modifyTradestatus (Baobiaoorder.unknown_state, Outtradeno); } log.info (outtradeno + "o status do pedido foi modificado para" + status); } else {// se a assinatura de verificação não passar o retorno "falhou"; } retornar "sucesso"; }Provavelmente esse é o caso, mas há menos notificações de pagamento bem -sucedido ao cliente e também existem alguns problemas de segurança.
Por fim, vamos resumir os problemas encontrados neste processo:
1. O código QR retornado por Alipay não pode ser aberto diretamente no navegador, mas deve ser usado para converter códigos QR para gerar códigos QR, ou você pode visualizá -los no site cli.im.
2. O código QR gerado pelo ambiente Alipay Sandbox só pode ser digitalizado usando a versão Sandbox do telefone celular Alipay. Se a versão normal das varreduras de Alipay, o código QR expirará e outros erros ocorrerão.
3. Se você não puder receber a notificação assíncrona enviada por Alipay após o pagamento, poderá usar o Postman e outras ferramentas para verificar se o notify_url que você preencheu pode ser acessado usando o IP público.
4. Se você encontrar o problema das permissões insuficientes de ISV, é porque não há assinatura de contrato ou o aplicativo não adicionou funções correspondentes e o aplicativo não pode ser usado sem online. Você pode escolher um aplicativo de sandbox durante o desenvolvimento.
5. Ao registrar a versão Sandbox do Alipay Mobile Phone, você pode entrar em contato com o atendimento ao cliente para solicitar uma conta
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.