لقد كنت أدرس دفع رمز QR الخاص بـ Alipay منذ فترة. يجب أن أقول إن وثيقة Alipay سيئة للغاية (على الأقل كانت من Mengbi عندما قرأتها لأول مرة). تبدو الأمثلة فوق المستند مختلفة تمامًا عن الأمثلة في العرض التوضيحي. في كثير من الأحيان ، تكون الأمثلة الموجودة أعلاه بسيطة للغاية ، في حين أن رمز العرض التجريبي معقد للغاية ، لذلك لم أكن أعرف الرمز الذي يجب استخدامه في البداية. في وقت لاحق ، نظرت بعناية إلى الكود في الحزمة التجريبية ووجدت أنه تم استدعاء واجهات أمثلة المستند. عندها فقط أدركت أنهم كانوا نفس الشيء ، لكن العرض التوضيحي لف واجهات الوثيقة فقط.
أولاً ، تقدم بطلب للحصول على حساب Alipay للشركة. يحتوي هذا الحساب على PID ، وتحتاج إلى إضافة تطبيق إلى هذا الحساب. كل تطبيق لديه appid ، ومفتاح عام وخاص. يمكن إنشاء المفاتيح العامة والخاصة من خلال الأدوات التي توفرها Alipay. بالإضافة إلى ذلك ، يحتاج مطورو Java إلى استخدام مفاتيح خاصة بتنسيق PKCS6. إذا احتاج التطبيق إلى استخدام وظيفة المسح ، فمن الضروري إضافة خيار الدفع الشخصي في التطبيق ، والذي يتطلب توقيع عقد. بعد التوقيع على وظيفة الدفع الشخصية ، لا يمكن استخدامه مباشرة لأن التطبيق يجب أن يكون عبر الإنترنت قبل استخدامه. لذلك ، يمكنك استخدام إصدار صندوق الرمل من التطبيق أثناء التطوير. يوفر Alipay إصدار Sandbox من Gateway و Alipay Public Key و PID و AppID ، والذي يجب تعديله أثناء التكوين.
يمكن للرمز استخدام الكود مباشرة في العرض التوضيحي ، أولاً استيراد واجهة برمجة التطبيقات التي توفرها Alipay في المشروع (لاحظ أنه ليس الرمز التجريبي) ، ثم استيراد رمز العرض التجريبي ، كما هو موضح في الشكل:
يمكن تشغيل ملف com.alipay.demo.trade.main مباشرة ، ولكن يجب تكوين ملف المورد:
# alipay gateway name ، partnerid و appid# هذا هو بوابة صندوق الرمل Open_Api_domain = https://openapi.alipaydev.com/gateway.domcloud_api_domain = http://mcloudmonitor.com/gateway.do# هذا هو uidpid merchant for sandbox = 2088102171721721721721717217217217172171717217217. في AppIdAppid لبيئة صندوق الرمل الخاص بك شخصيًا هنا = 2016082000300485 # RSA المفتاح الخاص ، المفتاح العمومي والمفتاح العام Alipay # ، يرجى ملء مفتاح التاجر الخاص بك هنا ونقله إلى PKCS8 Format private_key = miiceqibadanbgkqhkig9w0baqefaascammwggjfageaaogbamkxzrfr+rnvygbs9qz2ce1mcsibreaqan+5pf5+02hyj4hzcnttwqhfm91ih 3wypyhpm7xlbgj5ywjtgc4g1lz75r8a+ucyuxp8by1lv/44gi/tiflsgatfq73ocm9imxocrdyz2zcwqi1gv+b3udoy/da5w07grwizfzs6vq 1ragmbaaecgyeaqhc4grbsrckeinytk1vhqcj0yg11lvy85z3si0fny26dvs8r5gfydzc/mx5f8rnpuuyuhqn+4cquor3d/c291x1itov2nev lhejRoudknp4oqRiqt2w9pz8rzwzp2jcwvrvuf4ztpeimppmorp6sprfx6dlzg29sfi6gzwu6tkcqdp3mim1bhus3yonezgc69zn0/dgofk eix0s18qau1x4i1fejvtky4hpdwihpgyajm0ufg1lk8mtiunhpzrcnakea1qf6u1akjm6zsvdenrxedtcc75uvjgsyfjwhhx9pjyd9vx8nszv 0Z0U4V0ZG0N0YVHJ5LRO6U5FCQFRW1WIXNQJBALMCKZ8SVF/H9N6LIWMSPY6W5Q82KRLRC7WSCENSPQT0WQL5+SACG98M0XXY5J1HMIOLHXG ctvyrixowobivqcqctnanb4uz3q/86r/kukbvd3dirwlfryaho6yxp8oy+je/bv/359+vr3cxzyyldhzor9/tvspwr/y9q4jlem Q1TAKEALBU7+4EDZFAP7E/FMGYKD5DML8H2IAEUMRRCPL84GHFFK/7PSQ/40NGKXPTGY44NLHXCRPW5CZU6GQDINJOA ==#من فضلك املأ التاجر الخاص بك public_key هنا = MIGFMA0GCSQGSIBDQEBAQUAA4GNADCBIQKBGQDCL2AXUFQ572IABPAS9NBNZGKIAUXMQMP/UT3+FTNH8O+B83DU01QHXZVDSB98GD8OATO15W4 ceclibyauinzc ++ a/gvlasrst/g8ts1f+obov0yhy0oae30o9zndpypl6hexwm9mqskotyffm91a6mvw2ucno4evosxc0ulatawidaqab#this هو المفتاح العام لبيئة صندوق الرمل Alipay_public_key = MIGFMA0GCSQGSIB3DQEBAQUAA4GNADCBIQKBGQDIGHNNON7LLILLECLEKTD6BFRJ0GQGS2Y3MN1WMQMYH9ZEYWLZ5P1ZRAHRAHRAHBXAFCFSQSHSNFQ omaqzshrvjcqjsaw1jyqrxapdkbmr90dipixmiykxv4ggakpyj/6ftfy99uhpiqadd/uszqsefwo0atvp/65zi3eof7tcz32owpwidaqab# الحد الأقصى لعدد الاستفسارات وفاصل الاستعلام الفاصل (milliseconds) max_query_retry = 5query_duration = 5000# الحد الأقصى لعدد التراجع وفواصل التراجع (ms) في شخص max_cancel_retry = 3cancel_duration = 2000# معاملة ضمان مؤشر ترابط الجدولة الأولى (SecondSs)
ثم قم بتشغيل ملف main.java. بالنسبة إلى رمز الدفع لمسح رمز المسح في التطبيق الفعلي الخاص بنا ، يمكننا نسخ وظيفة test_trade_precreate () مباشرة في ملف main.java وإنشاء وظيفة في وحدة التحكم:
requestmapping (value = "/pay/alipay" ، method = requestMethod.post) الخريطة العامة <string ، string> alipay ( @requestparam مبلغ سلسلة ، requestparam int userid) {map <string ، string> map = new hashmap <string ، string> () ؛ // (مطلوب) لا يمكن أن يحتوي رقم الطلب الفريد في نظام ترتيب موقع Merchant ، مع 64 حرفًا فقط ، على رسائل وأرقام ورسومات. // من الضروري التأكد من عدم تكرار نظام التاجر. يوصى بإنشائه من خلال تسلسل قاعدة البيانات ، String OutTradeno = "XXXXX" + System.CurrentTimeMillis () + (Long) (Math.Random () * 10000000L) ؛ // (مطلوب) عنوان الطلب ، يصف تقريبًا غرض دفع المستخدم. على سبيل المثال ، "XXX Brand XXX Store يدفع شخصيًا ويقوم بمسح الرمز لاستهلاك" string thision = "pay" ؛ // (مطلوب) المبلغ الإجمالي للطلب هو 100 مليون يوان ، ولا يمكن أن يتجاوز 100 مليون يوان // إذا [المبلغ المخفض] ، [لم يتم خصم المبلغ] ، و [إجمالي مبلغ الطلب] في نفس الوقت ، يجب استيفاء الشروط التالية: [إجمالي المبلغ المبلغ] = [المبلغ المخفض] + [غير مخفضة المبلغ الإجمالي]. // (اختياري) لا يمكن خصم الطلب ، ويمكن تكوينه باستخدام النظام الأساسي التجاري لتكوين أنشطة الخصم. إذا لم يشارك الكحول في الخصم ، فسيتم ملء المبلغ المقابل في هذا الحقل // إذا لم يتم إرسال القيمة ، ولكن [إجمالي مبلغ الطلب] و [المبلغ المخفض] يتم إرساله ، فإن القيمة الافتراضية إلى [إجمالي مبلغ الطلب]-[المبلغ المخفض] سلسلة غير مفهوم = "0" ؛ // يتم استخدام معرف حساب ALIPAY الخاص بالبائع لدعم الدفع لحسابات الدفع المختلفة بموجب حساب عقد (دفع إلى حساب AliPay المقابل لـ Sellerid) // إذا كان هذا الحقل فارغًا ، فإنه يتخلف عن PID من التاجر الموقّع مع AliPay ، أي PID المقابل لسلسلة AppID = "20888102172172983" ؛ // وصف الطلب ، يمكنك وصف المعاملة أو المنتج بطريقة مفصلة ، مثل ملء "شراء 2 عنصرين في إجمالي 15.00 Yuan" Body Body = "3 عمليات شراء من 3 عناصر في إجمالي 20.00 يوان" ؛ // رقم مشغل التاجر ، أضف هذه المعلمة لإجراء إحصائيات المبيعات لـ Merchant Operator String OperatorId = "test_operator_id" ؛ // (مطلوب) رقم متجر التاجر ، من خلال رقم المتجر والواجهة الخلفية للتاجر ، يمكنك تكوين معلومات الخصم إلى المتجر بدقة. للحصول على تفاصيل ، يرجى الرجوع إلى alipay fechice super string storeid = "2088102172329883" ؛ . للحصول على التفاصيل ، يرجى الرجوع إلى الدعم الفني Alipay ExtendParams = New ExtendParams () ؛ ExtendParams.SetSysServiceProviderId ("2088100200300400500") ؛ // مهلة الدفع ، التي يتم تعريفها على أنها 120 دقيقة من Timoutexpress = timeout ؛ // // قائمة تفاصيل المنتج ، تحتاج إلى ملء تفاصيل منتج الشراء ، // list <SoundTail> gooddetaillist = new arraylist <Seaddetail> () ؛ // // إنشاء معلومات عن المنتج ، والمعلمات هي معرف المنتج (باستخدام National Standard) ، والاسم ، والوحدة في النقاط في النقاط) ، والكميات. إذا كنت بحاجة إلى إضافة فئات المنتجات ، فيرجى الرجوع إلى goodsdetail // goodtail goods1 = goodsdetail.newinstance ("goods_id001" ، "xxx small bread" ، 1000 ، 1) ؛ // // أضف إلى قائمة تفاصيل المنتج بعد إنشاء منتج // goodtaillist.add (good1) ؛ ///////////تواصل إنشاء المعلومات الأولى. المنتج الذي تم شراؤه من قبل المستخدم هو "فرشاة الأسنان السوداء" ، بسعر وحدة 5.00 يوان. لقد اشتريت قطعتين // goodsdetail goods2 = GoodteTail.NewInstance ("pould_id002" ، "xxx toothbrush" ، 500 ، 2) ؛ // goodtaillist.add (goods2) ؛ // Create a scan code to pay the request builder, set the request parameters AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder() .setSubject(subject) .setTotalAmount(totalAmount) .setOutTradeNo(outTradeNo) .setUndiscountableAmount(undiscountableAmount) .setSellerId(sellerId) .setBody (body) .SetOperatorId (properatorId) .SetStoreId (storeid) .setextendParams (extendparams) .SetTimeOutExpress (timeoutexpress) .setNotifyUrl ("http://xxx.xx.xx.xx مسار HTTP المحدد في خادم التاجر. تعيين حسب الحاجة. هنا وضعنا واجهة كتبنا أنفسنا. سنقدمه لاحقًا. //. alipayf2fprecrateSult result = tradeservice.tradeprecreate (builder) ؛ Switch (result.getTradEstatus ()) {Case Success: log.info ("alipay تم طلبها مسبقًا بنجاح :)") ؛ system.out.println ("alipay تم طلبها مسبقًا بنجاح :)") ؛ alipaytradeprecreateSponse استجابة = result.getResponse () ؛ // dumpresponse (استجابة) ؛ // system.out.println (response.getBody ()) ؛ // // // يجب تعديلها على المسار على جهاز التشغيل // string filepath = string.format (/user/liuyangl log.info ("filepath:" + filepath) ؛ // zxingutils.getqrcodeimge (response.getqrcode () ، 256 ، filepath) ؛ // system.out.println (response.getqrcode ()) ؛ // إنشاء طلب وإدراج قاعدة البيانات baobiaoorder = baobiaoorder جديد (userId ، OutTradeno ، "" ، double.parsedouble (المبلغ) ، تاريخ جديد () ، 1) ؛ baobiaoorderservice.insertorder (Order) ؛ map.put ("الحالة" ، "true") ؛ map.put ("qrcode" ، reponse.getqrcode ()) ؛ // العودة إلى كود QR العميل map.put ("OutTradeno" ، OutTradeno) ؛ خريطة العودة فشلت القضية: log.error ("فشل طلب ما قبل alipay !!!") ؛ System.out.println ("فشل الطلب المسبق Alipay !!!") ؛ system.out.println (result.getResponse (). getBody ()) ؛ استراحة؛ حالة غير معروفة: log.error ("استثناء النظام ، حالة الطلب غير معروف !!!") ؛ System.out.println ("استثناء النظام ، حالة الطلب غير معروف !!!") ؛ استراحة؛ الافتراضي: log.error ("حالة المعاملة غير المدعومة ، تعيد المعاملة استثناء !!!") ؛ System.out.println ("حالة المعاملة غير المدعومة ، إرجاع المعاملة الاستثناء !!!") ؛ استراحة؛ } map.put ("الحالة" ، "false") ؛ map.put ("msg" ، "النظام له استثناء ، يرجى المحاولة مرة أخرى لاحقًا!") ؛ خريطة العودة }المنطق هو أن المستخدم سيقوم بمسح الرمز على هاتفه المحمول لدفع Alipay ، وبعد استلامه ALIPAY ، سيرسل رسالة من الدفع الناجح إلينا لتعيين Detify_url ، كما هو موضح أدناه:
@requestmapping (value = "/pay/etemify" ، method = requestMethod.post) السلسلة العامة الإخطار (طلب httpservletrequest ، استجابة httpservletresponse) {log.info ("استلام الإخطار غير المتزامن alipay!") ؛ خريطة <string ، string> params = new hashmap <string ، string> () ؛ // استرداد جميع المعلمات للتحقق من تعداد التوقيع <Tring> parameTernames = request.getParameterNames () ؛ بينما (parameTernames.hasmoreElements ()) {String parameTerName = parameTerNames.nextElement () ؛ params.put (parameTername ، request.getParameter (parameTername)) ؛ } boolean signverified ؛ حاول {signverified = alipaysignature.rsacheckv1 (params ، configs.getalipaypublickey () ، "utf-8") ؛ } catch (alipayapiexception e) {E.PrintStackTrace () ؛ العودة "فشل" ؛ } if (signverified) {String OutTradeno = params.get ("Out_trade_no") ؛ log.info (OutTradeno + "Order Callback Detification.") ؛ // system.out.println ("تحقق من التوقيع بنجاح!") ؛ log.info ("تحقق من التوقيع بنجاح!") ؛ // إذا كان AppID في المعلمة يختلف عن appid ملء ، فهو إشعار استثناء إذا كان (! configs.getAppId (). يساوي (params.get ("app_id")))) العودة "فشل" ؛ } // ابحث عن الترتيب المقابل لرقم الطلب في قاعدة البيانات وقارن المبلغ مع المبلغ في قاعدة البيانات. إذا لم يتطابق مع ذلك ، فسيقوم أيضًا بإخطار استثناء Baobiaoorder Order = baobiaoorderservice.findorderbyouttradeno (OutTradeno) ؛ if (order == null) {log.warn (OutTradeno + "تحقق من هذا الترتيب دون التحقق!") ؛ العودة "فشل" ؛ } if (order.getAmount ()! = double.parsedouble (params.get ("Total_amount"))) {log.warn ("مختلف عن المبلغ في وقت الدفع ، هذا هو إشعار استثناء ويجب تجاهله!") ؛ العودة "فشل" ؛ } if (order.getStatus () == baobiaoorder.trade_success) إرجاع "النجاح" ؛ // إذا تم دفع الطلب بنجاح ، فتجاهل حالة سلسلة الإخطار هذه = params.get ("trade_status") ؛ if (status.equals ("wait_buyer_pay")) {// إذا كانت الحالة تنتظر دفع المستخدم إذا (order.getStatus ()! = baobiaoorder.wait_buyer_pay) baobiaoorderservice.modifyTradestatus (baobiaoorderderderder.wait_buyer_paypay ، } آخر إذا (status.equals ("trade_closed")) {// إذا كانت الحالة غير مدفوعة مهلة المعاملة غير مدفوعة ، أو يتم استرداد الدفع بالكامل إذا (order.getStatus ()! = baoOorder.trade_closed) baobiaoorderservice.modifytradestatus (baobiaoorderderderder_trade_tradeno ، } if if (status.equals ("trade_success") || status.equals ("trade_finished")) {// إذا تم دفع الحالة بنجاح إذا (order.getStatus ()! = baobiaoorderderderder_trade_success) baobiaoorderservice.modifytradestatus (baobiaoorderderderd.trade_success ، } آخر {baobiaoorderservice.modifyTradestatus (baobiaoorderder.unknown_state ، outtradeno) ؛ } log.info (OutTradeno + "تم تعديل حالة الطلب إلى" + حالة) ؛ } آخر {// إذا كان توقيع التحقق لا يمر "فشل" ؛ } إرجاع "النجاح" ؛ }ربما يكون هذا هو الحال ، ولكن هناك إخطارات أقل للدفع الناجح للعميل ، وهناك أيضًا بعض المشكلات الأمنية.
أخيرًا ، دعونا نلخص المشكلات التي واجهتها في هذه العملية:
1. لا يمكن فتح رمز الاستجابة السريعة التي تم إرجاعها بواسطة Alipay مباشرة في المتصفح ، ولكن يجب استخدامها لتحويل رموز QR لإنشاء رموز QR ، أو يمكنك عرضها من خلال موقع CLI.IM.
2. لا يمكن فحص رمز الاستجابة السريعة التي تم إنشاؤها بواسطة بيئة صندوق الرمل Alipay إلا باستخدام إصدار Sandbox من الهاتف المحمول Alipay. إذا كان الإصدار العادي من عمليات مسح Alipay ، فسيتم انتهاء رمز الاستجابة السريعة وسيحدث أخطاء أخرى.
3. إذا لم تتمكن من تلقي الإشعار غير المتزامن الذي أرسله AliPay بعد الدفع ، فيمكنك استخدام ساعي البريد والأدوات الأخرى للتحقق مما إذا كان يمكن الوصول إلى Notify_url الذي تملأه باستخدام IP العام.
4. إذا واجهت مشكلة عدم كفاية أذونات ISV ، فذلك لأنه لا يوجد توقيع عقد أو لم يضف التطبيق وظائف مقابلة ، ولا يمكن استخدام التطبيق بدون الإنترنت. يمكنك اختيار تطبيق صندوق الرمل أثناء التطوير.
5. عند تسجيل إصدار Sandbox من هاتف Alipay المحمول ، يمكنك الاتصال بخدمة العملاء لطلب حساب
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.