我现在工作的公司的主打产品是一款叫“乐秀”的视频剪辑编辑工具APP,产品可免费试用,如果付费购买会员的话,可以解锁更多的素材和功能。
原来的会员是买断的,买过一次即永久会员了。现在公司做了改变,会员机制改为类似腾讯视频会员这种包月的,还要支持微信支付宝代扣。其中支付宝代扣这部分的服务器端开发任务分配给了我。
支付宝商户代扣开发平台文档:https://docs.alipay.com/pre-open/20170601105911096277/cmgtz2
本文不会详细写下全部的开发流程,只对开发过程中比较关键的点作记录。
目前我了解到的支付宝代扣方式应该是两种,第一种是支付前签约,免密支付应该使用的是这种签约方式,用户可以先享受服务,后付款,相关业务比如上海地铁的先乘后付。
第二种是支付后签约,先付费后享受服务,我们平常在APP中看到的包月应该就是采用这种签约方式。
我们的代扣采用第二种签约方式。
接入的难点是第一个接口-alipay.trade.page.pay(统一收单下单并支付页面接口)。部分参数设置如下:
AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest(); AlipayTradePagePayModel model = new AlipayTradePagePayModel(); AgreementSignParams agreementSignParams = new AgreementSignParams(); agreementSignParams.setPersonalProductCode("GENERAL_WITHHOLDING_P");//固定值 model.setProductCode("GENERAL_WITHHOLDING"); model.setAgreementSignParams(agreementSignParams); alipayTradePagePayRequest.setBizModel(model); alipayTradePagePayRequest.setReturnUrl(reqPara.get("returnUrl")); alipayTradePagePayRequest.setNotifyUrl(MyConfigurer.getEvn("alipay.notifyUrl")); alipayTradePagePayResponse = alipayClient.pageExecute(alipayTradePagePayRequest,"get"); orderString = alipayTradePagePayResponse.getBody();// 就是orderString,可以直接给客户端请求,无需再做处理。 orderString = URLEncoder.encode(orderString, "UTF-8");
这里有几个点需要注意:
- personal_product_code传入的值为固定值GENERAL_WITHHOLDING_P
- sign_scene传入的值为固定值DEFAULT|DEFAULT
- return_url传入的值为APP端的scheme地址,供支付宝在用户支付完成后调用回到APP内指定页面。比如支付宝内淘宝页地址:taobao://
- notify_url传入的值为接受支付宝异步通知的URL,该URL要求可被外部访问
- 接口调用方式为pageExecute(request,"get")
在用户支付完成后,支付宝的服务器会向接入服务器发送支付异步通知和签约异步通知。
支付的异步通知地址为上述接口的notify_url,支付并签约或者用户在支付宝端解约的异步通知地址都是在调用接口的appid下的应用网关中进行配置的。
在支付宝后台中配置位置如下图
支付宝先支付后签约接入的比较复杂的就是上面的内容了,接下来的查询、解约等接口正常调用就好,支付宝接口调用的方式有多种,比如上面提到的pageExecute,支付宝支付接口调用的sdkExecute(request),如果不知道用那种调用方式,可以尝试下直接使用execute(request)。
另外,关于签约产品在APP上显示的自定义文案,如果是先付费后签约(alipay.trade.page.pay)的情况,目前我了解到的,只能将改文案交给支付宝相关人员,让支付宝去配置。这种情况和支付宝沟通过,是不支持配置多个不同的文案的。
如果是先签约(alipay.user.agreement.page.sign),则可以通过接口中的sub_merchant字段设置自定义文案。