赞
踩
电商项目中对接三方在线支付有支付宝、微信支付。业务是
越做越深入,越做越复杂。相信我,这是必然的规律。所有的业务没有
一上来就羽翼丰满,通常随着时间慢慢发展,逐渐增加这样那样的需
求,而作为开发出身的人,深知每一次需求变更都将是对技术和业务分
析的一次大考。一般牵一发而动全身。
一开始在线支付业务不是先天需求,而是由订单业务模块催生出来的场
景。尤其是在B2B业务中,订单支付一般走对公,要么是走线下,当然
如果有在线支付自然是锦上添花,但不是雪中送炭。因为增加一种需求
必须完整的考虑所有可能出现的业务缺陷,尽可能使所有业务分支形成
闭环。
在线支付,往细节分析,不仅要实现“统一下单”、支付发起、支付超时、支付取
消、重新支付、支付查询、支付回调、这些常规操作,还需要将这些操作融合到订
单业务的各个状态中,可以说围绕订单的生命周期,在线支付是穿插和环绕展开
的。
订单状态粗略按照:提交订单(待支付)、取消(未支付取消、已支付取消)、
订单已支付、订单捡货、订单发货、订单已签收、订单完成、
订单退款(部分退款、全部退款)、订单退货(整单退货,部分退货)、
订单换货(整单换货、部分换货)
当然各家做电商系统订单状态基本类似,自然也存在着不同之处。这里拆开每一种
状态都有非常多的业务细节在里面。
我们本文要分析的是订单取消状态与在线支付业务的关联性,和普遍的可见业务场
景。
支付状态简单来讲介于待支付和已支付两种,如果要问支付中算不算一种独立的状
态,从技术角度分析是这样的,也是存在的。
不过我们将支付状态与订单状态设计到同一张数据库表order表中需要多个字段来描
述业务中出现的各种数据状态。
参见第下图中的支付过程拆解。用户在页面中点击支付按钮的直接感官是一步完
成的。实际开发过程中与支付宝、微信对接需要两步,并且第二步支付动作是不与
后台系统发生请求与响应的,因为第二部操作是用户在客户端直接拉起支付宝支付
或者拉起微信支付的,是直接向三方支付平台发送支付请求的。
这里再复述一下正常的在线支付过程:
第一步:用户完成订单提交,并选择支付方式(微信/支付宝),点击按钮“立即
支付”
第二步:在点击立即支付按钮的一刻,客户端向后台发送请求“统一下单”,后台
将根据支付方式选择向微信或者支付宝发起“统一下单”API调用,让支付宝或者
微信后台记录将要交易的订单数据,等到微信或支付宝成功记录交易订单后会返
回预支付ID或预支付凭据给业务系统后台,后台将支付凭证返回给客户端,下一
步发起支付。
统一下单API的调用过程,要告知支付平台notify_rul(支付完成后的通知回调接口
地址,用来更新订单状态等),还要告知支付平台支付的超时等待时间。
微信统一下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder
文档地址:https://pay.weixin.qq.com/wiki/doc/api/index.html
支付宝统一下单接口:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay
文档地址:https://opendocs.alipay.com/apis
第三步:客户端获取支付凭证后,拉起支付宝支付或拉起微信支付,这时会看到
熟悉的支付页面(微信或支付宝),页面展示用户需要支付的订单金额,输入密
码后点击确认向微信或者支付宝发起支付,微信货支付宝根据支付凭证等参数校
验无误后完成记账,交易,返回成功信息。
第四步:微信或支付宝回调notify_url
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); request.setBizContent("{" + "\"out_trade_no\":\"20150320010101001\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + "\"total_amount\":88.88," + "\"subject\":\"Iphone6 16G\"," + "\"body\":\"Iphone6 16G\"," + "\"time_expire\":\"2016-12-31 10:05:01\"," + " \"goods_detail\":[{" + " \"goods_id\":\"apple-01\"," + "\"alipay_goods_id\":\"20010001\"," + "\"goods_name\":\"ipad\"," + "\"quantity\":1," + "\"price\":2000," + "\"goods_category\":\"34543238\"," + "\"categories_tree\":\"124868003|126232002|126252004\"," + "\"body\":\"特价手机\"," + "\"show_url\":\"http://www.alipay.com/xxx.jpg\"" + " }]," + "\"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," + "\"extend_params\":{" + "\"sys_service_provider_id\":\"2088511833207846\"," + "\"hb_fq_num\":\"3\"," + "\"hb_fq_seller_percent\":\"100\"," + "\"industry_reflux_info\":\"{\\\\\\\"scene_code\\\\\\\":\\\\\\\"metro_tradeorder\\\\\\\",\\\\\\\"channel\\\\\\\":\\\\\\\"xxxx\\\\\\\",\\\\\\\"scene_data\\\\\\\":{\\\\\\\"asset_name\\\\\\\":\\\\\\\"ALIPAY\\\\\\\"}}\"," + "\"card_type\":\"S0JP0000\"" + " }," + "\"goods_type\":\"0\"," + "\"timeout_express\":\"90m\"," + "\"promo_params\":\"{\\\"storeIdType\\\":\\\"1\\\"}\"," + "\"royalty_info\":{" + "\"royalty_type\":\"ROYALTY\"," + " \"royalty_detail_infos\":[{" + " \"serial_no\":1," + "\"trans_in_type\":\"userId\"," + "\"batch_no\":\"123\"," + "\"out_relation_id\":\"20131124001\"," + "\"trans_out_type\":\"userId\"," + "\"trans_out\":\"2088101126765726\"," + "\"trans_in\":\"2088101126708402\"," + "\"amount\":0.1," + "\"desc\":\"分账测试1\"," + "\"amount_percentage\":\"100\"" + " }]" + " }," + "\"sub_merchant\":{" + "\"merchant_id\":\"2088000603999128\"," + "\"merchant_type\":\"alipay: 支付宝分配的间连商户编号, merchant: 商户端的间连商户编号\"" + " }," + "\"merchant_order_no\":\"20161008001\"," + "\"enable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," + "\"store_id\":\"NJ_001\"," + "\"disable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," + "\"qr_pay_mode\":\"1\"," + "\"qrcode_width\":100," + "\"settle_info\":{" + " \"settle_detail_infos\":[{" + " \"trans_in_type\":\"cardAliasNo\"," + "\"trans_in\":\"A0001\"," + "\"summary_dimension\":\"A0001\"," + "\"settle_entity_id\":\"2088xxxxx;ST_0001\"," + "\"settle_entity_type\":\"SecondMerchant、Store\"," + "\"amount\":0.1" + " }]," + "\"settle_period_time\":\"7d\"" + " }," + "\"invoice_info\":{" + "\"key_info\":{" + "\"is_support_invoice\":true," + "\"invoice_merchant_name\":\"ABC|003\"," + "\"tax_num\":\"1464888883494\"" + " }," + "\"details\":\"[{\\\"code\\\":\\\"100294400\\\",\\\"name\\\":\\\"服饰\\\",\\\"num\\\":\\\"2\\\",\\\"sumPrice\\\":\\\"200.00\\\",\\\"taxRate\\\":\\\"6%\\\"}]\"" + " }," + "\"agreement_sign_params\":{" + "\"personal_product_code\":\"GENERAL_WITHHOLDING_P\"," + "\"sign_scene\":\"INDUSTRY|CARRENTAL\"," + "\"external_agreement_no\":\"test\"," + "\"external_logon_id\":\"13852852877\"," + "\"sign_validity_period\":\"2m\"," + "\"third_party_type\":\"PARTNER\"," + "\"buckle_app_id\":\"1001164\"," + "\"buckle_merchant_id\":\"268820000000414397785\"," + "\"promo_params\":\"{\\\"key\\\",\\\"value\\\"}\"" + " }," + "\"integration_type\":\"PCWEB\"," + "\"request_from_url\":\"https://\"," + "\"business_params\":\"{\\\"data\\\":\\\"123\\\"}\"," + "\"ext_user_info\":{" + "\"name\":\"李明\"," + "\"mobile\":\"16587658765\"," + "\"cert_type\":\"IDENTITY_CARD\"," + "\"cert_no\":\"362334768769238881\"," + "\"min_age\":\"18\"," + "\"fix_buyer\":\"F\"," + "\"need_check_info\":\"F\"" + " }" + " }"); AlipayTradePagePayResponse response = alipayClient.pageExecute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); }
function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":"wx2421b1c4370ec43b", //公众号ID,由商户传入 "timeStamp":"1395712654", //时间戳,自1970年以来的秒数 "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串 "package":"prepay_id=u802345jgfjsdfgsdg888", "signType":"MD5", //微信签名方式: "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ){ // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } }); } if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{ onBridgeReady(); }
1.统一支付 设置了超时属性,则没有在规定时间内完成支付的情况
2.网络延迟,网络不可用导致的不能正常支付情况
3.用户取消支付
4.用户支付页面等待超时
由于产品新增加了好友代付功能,在技术开发过程中发现产品未曾考
虑到的边界问题。
假设用户下单后选择好友代付,将订单分享给好友,好友打开这个页
面选择代付,如果好友正在填写支付密码的过程中,用户自己取消了
订单,一定不能造成订单已经取消,好友还支付成功的现象。
另外一种场景,用户下单后因占用实时库存,订单有15分钟的支付等
待期,到期未支付系统会自动取消订单用以释放库存。假设订单被分
享给好友代付,而后台恰恰也支付过程中或支付前取消了订单。
以上这两种情况是必须避免出现的,原因是取消订单的操作和支付订
单的操作是异步进行的,如果常规情况下,没有代付操作,没有自动
取消订单操作,用户下单后由用户自己决定是支付还是取消则不会有
取消和支付异步进行的问题。
第二张图详细分析和规划了订单取消、订单支付异步进行的的技术方案。可以完美
规避上述的问题。
要实现这个技术方案,统一下单的数据记录至关重要,因为在这个时间节点发生之
前订单一直处于待支付状态
1.如果订单没有统一下单记录说明没有发生过支付动作。
2.如果已经有过统一下单记录而没有完成支付,说明订单正处于支付过程中
3.如果有统一下单记录,而支付超时,此时不论是支付,还是取消订单 都是安全
的。
**所以对于统一下单和订单取消对于第三种情况需要有锁定机制,谁先抢占锁谁就
有执行的机会**。
4.自动取消订单任务对订单实效判断需要注意的点,有两个时间点
1.订单提交开始到订单已支付之间的有效期,我们业务上设计15分钟
2.用户开始支付到支付超时的这段时间,这个时间我们设计为5分钟
3.实际上用户开始支付到支付超时这段时间是有移动区间的,可以在15分钟区间内,已可能在14分59秒开始直到20分钟支付超时。
所以取消订单需要判断订单状态和支付时间,两个时间区间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。