J'ai étudié le paiement du code QR d'Alipay il y a quelque temps. Je dois dire que le document Alipay est vraiment mauvais (au moins c'était de Mengbi quand je l'ai lu pour la première fois). Les exemples ci-dessus du document semblent complètement différents des exemples de la démo. Souvent, les exemples ci-dessus du document sont très simples, tandis que le code de démo est très compliqué, donc je ne savais pas quel code utiliser au début. Plus tard, j'ai soigneusement examiné le code dans le package de démonstration et j'ai constaté que les interfaces des exemples de documents étaient également appelées. Ce n'est qu'alors que je me suis rendu compte que c'était la même chose, mais une démo n'a enroulé que les interfaces du document.
Premièrement, demandez un compte Alipay d'une entreprise. Ce compte a un PID et vous devez ajouter une application à ce compte. Chaque application a un AppID et une clé publique et privée. Des clés publiques et privées peuvent être générées via des outils fournis par Alipay. De plus, les développeurs Java doivent utiliser des clés privées au format PKCS6. Si l'application doit utiliser la fonction de numérisation, il est nécessaire d'ajouter l'option de paiement en personne dans l'application, qui nécessite de signer un contrat. Après avoir signé la fonction de paiement en personne, il ne peut pas être utilisé directement car la demande doit être en ligne avant de pouvoir être utilisée. Par conséquent, vous pouvez utiliser la version sandbox de l'application pendant le développement. Alipay fournit la version sandbox de la passerelle, Alipay Public Key, PID et AppID, qui doivent être modifiées lors de la configuration.
Le code peut utiliser directement le code dans la démo, importe d'abord l'API fournie par Alipay dans le projet (notez qu'il ne s'agit pas du code de démonstration), puis importe le code de démonstration, comme indiqué sur la figure:
Ce fichier com.alipay.demo.trade.main peut être exécuté directement, mais un fichier de ressources doit être configuré:
# Nom de la passerelle Alipay, partenaireId et AppID # Ceci est la passerelle de l'environnement sandbox open_API_DOMAIN = https://openapi.alipaydev.com/gateway.domcloud_api_domain = http://mcloudmonitor.com/gateway.do# C'est le Merchant uidpid pour l'environnement de sandbox = 20881021723298333 pour l'environnement de sandbox = 20881021723298383 pour le Sandbox Environment = 20881021723298333 pour le sandbox Environ L'applidappid pour votre environnement de bac à sable en personne ici = 2016082000300485 # clé privée RSA, clé publique et clé publique Alipay # Veuillez remplir votre clé privée marchande ici et transférer au format PKCS8 private_key = Miiceqibadanbgkqhkig9w0baqefaascammwggjfageaaogbamkxzrfr + rnvygbs9qz2ce1mcsibreaqan + 5pf5 + 02hyj4hzcnttwqhfm91ih 3WYPYHPM7XLBGJ5YWJTGC4G1LZ75R8A + UCYUXP8BY1LV / 44GI / TIFLSGATFQ73OCM9IMXOCRDYZ2ZCWQI1GV + B3UDOY / DA5W07GRWIZFZS6VQ 1ragmbaaecgyeaqhhc4grbsrckeinytk1vhqcj0yg11lvy85z3si0fny26dvs8r5gfydzc / mx5f8rnpuUyuhqn + 4cqor3d / c291x1itov2nev2nev2 Lhejroudknp4oqriqt2w9pz8rzwzp2jcwvrvuf4ztpeIMPPMorp6Sprfx6dlzg29Sfi6GZWU6TKCQQDP3MIM1BHUS3yOneZGQC69ZN0 / DGOFK eix0s18qau1x4i1fejvtky4hpdwihpgyajm0ufg1lk8mtiunhpzrcnakea1qf6u1akjm6zsvdenrxedtcc75uvjgsyfjwhhx9pjyd9vx8nszv 0Z0U4V0ZG0N0YVHJ5LRO6U5FCQFRW1WIXNQJBALMCKZ8SVF / H9N6LIWMSPY6W5Q82KNRLRC7WSENSPQT0WQL5 + SACG98M0XXY5J1HMIOLHXG Ctvyrixowobivqccqqctnanb4uz3q / 86r / kukbvd3dirwlfryaho6yxp8oy + je / bv / 359 + vr3cxzyyldhzor9 / tvspwr / y9q4jlem Q1TaKEALBU7 + 4EDZFAP7E / FMGYKD5DML8H2IAEUMRRCPL84GHFFK / 7PSQ / 40NGKXPTGY44NLELHXCRPW5CZU6GQDINJOA == # s'il vous plaît s'il vous plaît Remplissez votre marchand public_key ici = MIGFMA0GCSQGSIBDQEBAQUAA4GNADCBIQKBGQDCL2AXUFQ572IABPAS9NBNZGKIAUXMQMP / UT3 + FTNH8O + B83DU01QHXZVDSB98GD8OOTO15W4 Ceclibyauinzc ++ a / gvlasrst / g8ts1f + obov0yhy0oae30o9zndpypl6hexwm9mqskotyffm91a6mvw2ucno4evosxc0ulatawidaqab # ceci est la clé publique de l'environnement de sandbox alipay_public_key = Migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqdighnon7llillketd6bfrj0gqgs2y3mn1wmqmyh9zeywlz5p1zrahrahrahbxafcfsqshsnfq OMAQZSHRVJCQJSAW1JYQRXAPDKBMR90DIPIXMIYKXV4GGAKPYJ / 6FTFY99UHPIQ0QADD / USZQSEFWO0ATVP / 65ZI3EOF7TCZ32OWPWIDAQAB # Nombre maximum de requêtes et d'intervalle de requête (millisecondes) max_query_retry = 5Query_Duration = 5000 # Nombre maximum d'intervalles et d'intervalles d'annulation (MS) en personne Max_Cancel_retry = 3Cancel_Duration = 2000 # Transaction Garantie Thread First Scheduling Dulay
Exécutez ensuite le fichier main.java. En ce qui concerne le code de paiement pour le code de numérisation dans notre application réelle, nous pouvons copier directement la fonction test_trade_preate () dans le fichier main.java et créer une fonction dans le contrôleur:
@RequestMapping (value = "/ pay / alipay", méthode = requestMethod.Post) public map <string, string> alipay (@requestParam String montant, @RequestParam int userId) {map <string, string> map = new hashmap <string, string> (); // (requis) Le numéro de commande unique dans le système de commande du site Web marchand, avec seulement 64 caractères, ne peut contenir que des lettres, des chiffres et des soulignements. // Il est nécessaire de s'assurer que le système marchand ne peut pas être répété. Il est recommandé de le générer via la séquence de la base de données, String OuttraDeno = "xxxxx" + System.Currenttimemillis () + (long) (math.random () * 10000000l); // (requis) le titre de commande, décrit à peu près l'objectif de paiement de l'utilisateur. Par exemple, "La marque XXX XXX Store paie en personne et analyse le code pour consommer" String Subject = "Pay"; // (requis) Le montant total de la commande est de 100 millions de RMB et ne peut dépasser 100 millions RMB // si [montant réduit], [montant non actualisé], et [le montant total de la commande] sont transmis en même temps, les conditions suivantes doivent être remplies: [Montant total de la commande] = [Montant réduit] + [NON MONTAGE DU MONTAGE] STRING TOTALAMOUNT = Montant; // (facultatif) La commande ne peut pas être réduite et peut être configurée avec la plate-forme marchande pour configurer les activités de réduction. Si l'alcool ne participe pas à la remise, le montant correspondant sera rempli dans ce champ // Si la valeur n'est pas transmise, mais [le montant total de la commande] et le montant réduit] sont transmis, la valeur par défaut est par défaut de [montant total de commande] - [Montant réduit] chaîne Undeccountableamount = "0"; // L'ID de compte Alipay du vendeur est utilisé pour prendre en charge le paiement à différents comptes de paiement dans le cadre d'un compte contrat (payer au compte Alipay correspondant à Sellerid) // Si ce champ est vide, il est par défaut au PID du marchand signé avec Alipay, c'est-à-dire le PID correspondant à l'Appid String Sellerid = "208810217232983" "; // Description de la commande, vous pouvez décrire la transaction ou le produit de manière détaillée, comme le remplissage de "2 achats de 2 articles au total 15,00 yuan" String Body = "3 achats de 3 articles au total 20,00 yuans"; // Numéro d'opérateur marchand, ajoutez ce paramètre pour effectuer des statistiques de vente pour l'opérateur marchand opératorId = "test_operator_id"; // (obligatoire) Numéro de magasin marchand, via le numéro de magasin et le backend marchand, vous pouvez configurer avec précision les informations de réduction au magasin. Pour plus de détails, veuillez consulter Alipay Technical Support String String StoreID = "2088102172329883"; // Paramètres d'extension commerciale, vous pouvez actuellement ajouter le numéro de fournisseur de système attribué par Alipay (via la méthode SetSyServiceProviderid). Pour plus de détails, veuillez consulter Alipay Technical Support ExtendParams ExtendParams = new ExtendParams (); extendParams.SetSyServiceProviderid ("2088100200300400500"); // Timeout de paiement, défini comme 120 minutes de chaîne TIMEUTExpress = délai d'expiration; // // Liste des détails du produit, vous devez remplir les détails du produit d'achat, // list <woodsdetail> bourse de bourse de bourse = les paramètres ArrayList <woodsdetail> (); // // Créer une information de produit, les paramètres sont le produit du produit (en utilisant la norme nationale, le nom, le prix de l'unité (unité dans les points) et la question. Si vous avez besoin d'ajouter des catégories de produits, veuillez vous référer à des marchandises // biens de biens 1 = biens de baignade. Le produit acheté par l'utilisateur est une "brosse à dents noire", avec un prix unitaire de 5,00 yuans. J'ai acheté deux pièces // marchandises de marchandises 2 = marchandises. // Créer un code de numérisation pour payer le constructeur de la demande, définissez les paramètres de demande AlipayTradePremeRaeSeSetBuilder Builder = new AlipayTradePrerateRequestBuilder () .SetSubJe .SetBody (Body) .SetOperatorId (OperatorId) .SetStoreId (StoreID) .SeTextendParams (ExtendParams) .SetTimeatexpress (timeoutexpress) .setNotifyUrl ("http://xxx.xx.xxx.xxx:8080/baobiao/pay/Notify"); Chemin HTTP spécifié dans le serveur marchand. Définir au besoin. Ici, nous définissons une interface que nous nous sommes écrites. Nous le présenterons plus tard. // .SetGoodsdetailList (marchandises); Alipayf2fprecreaSult Result = TradeService.TradePrereate (Builder); switch (result.getTradestatus ()) {Case Success: Log.info ("Alipay précommandé avec succès :)"); System.out.println ("Alipay précommandé avec succès :)"); AlipayTraDeprecreaterSponse Response = result.getResponse (); // DumpResponse (Response); // System.out.println (réponse.getBody ()); // // // doit être modifié sur le chemin de la machine de course // String FilePath = String.Format ("/ use log.info ("filepath:" + filepath); // zxingutils.getqrcodeiMge (réponse.getqrcode (), 256, filepath); // system.out.println (réponse.getQrcode ()); // Générez une commande et insérez la base de données Baobiaoorder Order = new Baobiaoorder (UserId, Outtradeno, "", double.parsedouble (montant), new Date (), 1); baobiaoorderservice.insertorder (ordre); map.put ("statut", "true"); map.put ("qrcode", réponse.getQrcode ()); // Retour au client QR Code Map.put ("Outtradeno", OutTradeno); carte de retour; Échec du cas: Log.Error ("Alipay Pré-commande a échoué !!!"); System.out.println ("Alipay Précommande a échoué !!!"); System.out.println (result.getResponse (). GetBody ()); casser; cas inconnu: log.Error ("Exception système, état de précommande inconnu !!!"); System.out.println ("Exception système, état de précommande inconnu !!!"); casser; par défaut: log.Error ("Statut de transaction non pris en charge, transaction renvoie l'exception !!!"); System.out.println ("Statut de transaction non pris en charge, transaction Renvoie l'exception !!!"); casser; } map.put ("statut", "false"); map.put ("msg", "Le système a une exception, veuillez réessayer plus tard!"); carte de retour; }La logique est que l'utilisateur scannera le code sur son téléphone mobile pour payer Alipay, puis après que Alipay l'a reçu, il nous enverra un message de paiement réussi pour définir Notify_url, comme indiqué ci-dessous:
@RequestMapping (value = "/ pay / notify", méthode = requestMethod.post) public string notifyResult (httpservletRequest request, httpservletResponse réponse) {log.info ("Reçu la notification asynchronique Alipay!"); Map <string, string> params = new hashmap <string, string> (); // Récupère tous les paramètres pour vérifier la signature énumération <string> Paramètres = request.getParameTames (); while (ParameTernames.HasmoreElements ()) {String ParameterName = Parameterames.NextElement (); Params.put (ParameterName, request.getParameter (ParameterName)); } booléen significatif; try {SignVerified = alipaySignature.rsacheckv1 (params, configs.getalipaypublickey (), "utf-8"); } catch (alipayapiexception e) {e.printStackTrace (); retourner "échoué"; } if (signneified) {String outraDeno = params.get ("out_trade_no"); Log.info (Outtradeno + "Commande Rappel Notification."); // System.out.println ("Vérifier la signature avec succès!"); Log.info ("Vérifiez la signature avec succès!"); // Si l'AppID dans le paramètre est différent de l'AppID rempli, il s'agit d'une notification d'exception si (! Configs.getAppid (). Equals (params.get ("app_id")))) {log.warn ("différent de l'Apid au moment du paiement, il s'agit d'une notification d'exception et doit être ignorée!"); retourner "échoué"; } // Trouvez l'ordre correspondant au numéro de commande dans la base de données et comparez son montant avec le montant de la base de données. S'il ne correspond pas, il informera également l'exception de Baobiaoor Order = BaobiaoRerderService.FindorderByoutTradeno (Outtradeno); if (ordonnance == null) {log.warn (untradeno + "Vérifiez cet ordre sans vérifier!"); retourner "échoué"; } if (order.getamount ()! = double.parsedouble (params.get ("total_amount"))) {log.warn ("différent du montant au moment du paiement, il s'agit d'une notification d'exception et doit être ignorée!"); retourner "échoué"; } if (order.getStatus () == baobiaoorder.trade_success) renvoie "succès"; // Si l'ordre a été payé avec succès, ignorez cette chaîne de notification status = params.get ("Trade_status"); if (status.equals ("wait_buyer_pay")) {// si le statut attend le paiement de l'utilisateur if (order.getStatus ()! = baobiaoorder.wait_buyer_pay) baobiaoorderservice.modifytradestatus (baobiaoorder.wait_buyer_pay, outradeno); } else if (status.equals ("Trade_Closed")) {// Si le statut est fermé de transaction non rémunéré, ou le paiement est entièrement remboursé if (order.getStatus ()! = baobiaoorder.trade_closed) baobiaoorderservice.modifytradestatu (baobiaoorder.trade_closed, outtradeno); } else if (status.equals ("Trade_success") || status.equals ("Trade_Finished")) {// si le statut est payé avec succès if (order.getStatus ()! = baobiaoorder.trade_success) baobiaoorderservice.modifytradestatus (baobiaoorder.trade_succress, Outtradestatus; } else {baobiaoorderservice.modifyTradestatus (baobiaoorder.unknown_state, outradeno); } log.info (undtradeno + "L'état de l'ordre a été modifié en" + statut); } else {// Si la signature de vérification ne passe pas de retour "a échoué"; } return "succès"; }C'est probablement le cas, mais il y a moins de notifications de paiement réussi au client, et il y a aussi des problèmes de sécurité.
Enfin, résumons les problèmes rencontrés dans ce processus:
1. Le code QR renvoyé par Alipay ne peut pas être ouvert directement dans le navigateur, mais doit être utilisé pour convertir les codes QR pour générer des codes QR, ou vous pouvez les visualiser via le site Web CLI.IM.
2. Le code QR généré par l'environnement Alipay Sandbox ne peut être analysé qu'à l'aide de la version sandbox du téléphone mobile Alipay. Si la version normale d'Alipay scanne, le code QR expirera et d'autres erreurs se produiront.
3. Si vous ne pouvez pas recevoir la notification asynchrone envoyée par Alipay après le paiement, vous pouvez utiliser Postman et d'autres outils pour vérifier si le Notify_url que vous avez rempli peut être accessible à l'aide de l'IP publique.
4. Si vous rencontrez le problème des autorisations ISV insuffisantes, c'est parce qu'il n'y a pas de signature de contrat ou que l'application n'a pas ajouté de fonctions correspondantes, et l'application ne peut pas être utilisée sans en ligne. Vous pouvez choisir une application Sandbox pendant le développement.
5. Lors de l'enregistrement de la version sandbox du téléphone mobile Alipay, vous pouvez contacter le service client pour demander un compte
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.