支付宝支付(四):周期扣款

您所在的位置:网站首页 支付宝相互宝在哪里看扣款 支付宝支付(四):周期扣款

支付宝支付(四):周期扣款

2024-07-16 07:41| 来源: 网络整理| 查看: 265

目录

一、调用支付宝主动签约接口

二、参数说明

三、查询签约结果接口

四、签约成功,根据签约协议号,发起主动扣款

五、查询扣款结果接口

六、变更签约用户,下次扣款日期

七、取消签约协议接口

一、调用支付宝主动签约接口

1、该接口返回的字符串,由前端生成二维I码后,可使用支付宝直接扫码,打开签约页面

public String aliPayPageSign(AliPayBo bo) { AlipayClient alipayClient = oldAliPayConfig.initAliPayClient(); AlipayUserAgreementPageSignRequest request = new AlipayUserAgreementPageSignRequest(); Map optionalArgs = new HashMap(); //周期扣款销售产品码固定为CYCLE_PAY_AUTH。 optionalArgs.put("product_code", "CYCLE_PAY_AUTH"); //周期扣款个人签约产品码固定为CYCLE_PAY_AUTH_P optionalArgs.put("personal_product_code","CYCLE_PAY_AUTH_P"); //协议签约场景,参见下文sign_scene参数说明 INDUSTRY|EDU教育行业 optionalArgs.put("sign_scene", AliPayConstant.SIGN_SCENE); // 商户签约号,代扣协议中标示用户的唯一签约号(确保在商户系统中唯一 optionalArgs.put("external_agreement_no",bo.getExternalAgreementNo()); /**请按当前接入的方式进行填充,且输入值必须为文档中的参数取值范围, * 1. ALIPAYAPP (钱包h5页面签约) * 2. QRCODE(扫码签约) * 3. QRCODEORSMS(扫码签约或者短信签约)*/ Map accessParams = new HashMap(); accessParams.put("channel","ALIPAYAPP"); optionalArgs.put("access_params",accessParams); /**周期管控规则参数period_rule_params,在签约周期扣款产品(如CYCLE_PAY_AUTH_P)时必传,在签约其他产品时无需传入。 周期扣款产品,会按照这里传入的参数提示用户,并对发起扣款的时间、金额、次数等做相应限制 */ Map periodRuleParams = new HashMap(); //周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH periodRuleParams.put("period_type","DAY"); //30天为一个扣款周期 periodRuleParams.put("period","30"); /**首次执行时间execute_time是周期扣款产品必填,即商户发起首次扣款的时间。精确到日,格式为yyyy-MM-dd 结合其他必填的扣款周期参数,会确定商户以后的扣款计划。发起扣款的时间需符合这里的扣款计划 首次扣款日期:当前时间+30 ; 目前允许商户在约定日期之前5天(不含扣款日当天)开始扣款 */ periodRuleParams.put("execute_time", DateUtils.dateToStr(new Date())); /**单次扣款最大金额single_amount是周期扣款产品必填,即每次发起扣款时限制的最大金额,单位为元。商户每次发起扣款都不允许大于此金额*/ periodRuleParams.put("single_amount",bo.getSingleAmount()); optionalArgs.put("period_rule_params",periodRuleParams); //签约参数。如果希望在sdk中支付并签约,需要在这里传入签约信息。周期扣款场景 product_code 为 CYCLE_PAY_AUTH 时必填 String requestJson = JSONUtil.toJsonStr(optionalArgs); log.info("用户{}:发起周期扣款签约请求,入参:{}",bo.getExternalAgreementNo(),requestJson); request.setBizContent(requestJson); AlipayUserAgreementPageSignResponse response; try { response = alipayClient.pageExecute(request,"get"); if(response.isSuccess()){ log.info("用户{}:周期扣款,发起签约成功",bo.getExternalAgreementNo()); //获取需提交的form表单 return response.getBody(); } log.info("用户{}:周期扣款,发起签约失败:{}",bo.getExternalAgreementNo(),response.getSubMsg()); } catch (AlipayApiException e) { e.printStackTrace(); log.error("用户{}:周期扣款,发起签约异常:{}",bo.getExternalAgreementNo(),e); } return null; }

2、我在这里会同步生成1条,用户的申请记录,用于后续定任务,发起主动扣款

CREATE TABLE `dx_member_first_sign_record` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `member_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT '会员ID', `order_no` varchar(50) NOT NULL DEFAULT '' COMMENT '会员订单编号', `external_agreement_no` varchar(50) NOT NULL DEFAULT '-1' COMMENT '商户签约号', `buy_status` tinyint(1) NOT NULL DEFAULT '-1' COMMENT '扣费状态(0:未扣款 1:成功 2:失败)', `goods_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT '会员商品ID', `goods_name` varchar(50) DEFAULT '-1' COMMENT '会员商品名称', `goods_length` int(4) DEFAULT '0' COMMENT '充值时长(天)', `consumer_id` bigint(20) NOT NULL DEFAULT '1' COMMENT '买家ID', `consumer_role` tinyint(1) NOT NULL DEFAULT '1' COMMENT '买家角色(1:供货商 2:代销商)', `pay_amount` bigint(20) NOT NULL DEFAULT '0' COMMENT '支付金额', `finish_time` datetime DEFAULT NULL COMMENT '扣款完成时间', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `again_time` datetime DEFAULT NULL COMMENT '再次申请时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remark` varchar(200) DEFAULT NULL COMMENT '扣费说明', PRIMARY KEY (`id`), KEY `idx_order_no` (`order_no`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员先签约后扣费记录表';  二、参数说明

1、external_agreement_no  由系统自动生成,确保全局唯一

2、使用老版本SDK

3、周期可以选择自然月和固定天

4、我使用的是定时任务,完成后续的签约成功的首次扣款,所以execute_time,下次扣款日期设置的是当天

5、sign_scene 协议签约场景,参见下文sign_scene参数说明,我使用的是INDUSTRY|EDU教育行业

三、查询签约结果接口

1、根据签约结果,发起首次扣款,如果签约时设置的execute_time 不在规定的时间范围内,支付宝会返回:扣款失败,协议不在有效范围内

2、代码如下:

public AlipayUserAgreementQueryResponse queryAliPaySign(AliPayBo bo) { AlipayClient alipayClient = oldAliPayConfig.initAliPayClient(); AlipayUserAgreementQueryRequest request = new AlipayUserAgreementQueryRequest(); Map requestMap = new HashMap(); requestMap.put("personal_product_code","CYCLE_PAY_AUTH_P"); requestMap.put("sign_scene",AliPayConstant.SIGN_SCENE); requestMap.put("external_agreement_no",bo.getExternalAgreementNo()); String requestJson = JSONUtil.toJsonStr(requestMap); log.info("{}:查询周期扣款签约结果入参:{}",bo.getExternalAgreementNo(),requestJson); request.setBizContent(requestJson); AlipayUserAgreementQueryResponse response = null; try { response = alipayClient.execute(request); if (response.isSuccess()) { log.info("{}:查询周期扣款签约结果,调用成功",bo.getExternalAgreementNo()); return response; }else { log.info("{}:查询周期扣款签约结果,调用失败:{}",bo.getExternalAgreementNo(),response.getSubMsg()); } } catch (AlipayApiException e) { e.printStackTrace(); } return null ; } 四、签约成功,根据签约协议号,发起主动扣款

1、签约协议号为,查询签约结果接口返回字段

2、代码如下:

public AlipayTradePayResponse aliPayTradePayByAuthCode(AliPayBo bo) { AlipayClient alipayClient = oldAliPayConfig.initAliPayClient(); AlipayTradePayRequest request = new AlipayTradePayRequest(); Map requestMap = new HashMap(); //商户订单号 requestMap.put("out_trade_no", bo.getOutTradeNo()); //必填,周期扣款代扣场景固定值 requestMap.put("scene","deduct_pay"); //用户签约号 agreement_no requestMap.put("auth_code",bo.getAgreementNo()); 周期扣款固定 requestMap.put("product_code","CYCLE_PAY_AUTH"); //订单标题 requestMap.put("subject",bo.getSubject()); //本次扣款金额 requestMap.put("total_amount",bo.getTotalAmount()); String requestJson = JSONUtil.toJsonStr(requestMap); log.info("{}:查询签约用户,进行自动续期扣费:{}",bo.getAgreementNo(),requestJson); request.setBizContent(requestJson); AlipayTradePayResponse response =null; try { response = alipayClient.execute(request); if(response.isSuccess()){ log.info("{}:周期扣款,主动扣费成功",bo.getAgreementNo()); }else { log.info("{}:周期扣款,主动扣费失败:{}",bo.getAgreementNo(),response.getSubMsg()); } } catch (Exception e) { e.printStackTrace(); } return response; }

3、此接口为老版SDK接口

五、查询扣款结果接口

1、该接口用于,根据商户生成的订单号,查询支付结果

2、根据支付结果,完成后续的业务操作:修改订单状态,增加会员有效期等业务操作

public AlipayTradeQueryResponse queryAliPayTradeByOrderNo(String outTradeNo) { //统一收单线下交易查询 AlipayTradeQueryResponse response = null; try { response = Factory.Payment.Common().query(outTradeNo); if(ResponseChecker.success(response)){ log.info("{}:查询支付结果,调用成功",outTradeNo); return response; }else { log.info("{}:查询支付结果,调用失败:{}",outTradeNo,response.getSubMsg()); } } catch (Exception e) { e.printStackTrace(); } return null; } 六、变更签约用户,下次扣款日期

1、因为我们系统的会员有效期有多种途径增加,因为对于签约用户的下次扣款日期,和会员到期时间同频,在会员到期时间增加后,应同步延顺下次扣款日期

public AlipayUserAgreementExecutionplanModifyResponse aliPayModifyPlan(AliPayBo bo) { AlipayClient alipayClient = oldAliPayConfig.initAliPayClient(); AlipayUserAgreementExecutionplanModifyRequest request = new AlipayUserAgreementExecutionplanModifyRequest(); Map requestMap = new HashMap(); requestMap.put("agreement_no",bo.getAgreementNo()); requestMap.put("deduct_time",bo.getDeductTime()); String requestJson = JSONUtil.toJsonStr(requestMap); log.info("{}:周期扣款-修改协议执行计划入参:{}",bo.getAgreementNo(),requestJson); request.setBizContent(requestJson); try { AlipayUserAgreementExecutionplanModifyResponse response = alipayClient.execute(request); if(response.isSuccess()){ log.info("{}:周期扣款-修改协议执行计划,调用成功",bo.getAgreementNo()); return response; } else { log.info("{}:周期扣款-修改协议执行计划,调用失败:{}",bo.getAgreementNo(),response.getSubMsg()); } } catch (AlipayApiException e) { e.printStackTrace(); log.error("{}:周期扣款-修改协议执行计划,调用异常:{}",bo.getAgreementNo(),e); } return null; } 七、取消签约协议接口

1、用于提供给用户,主动解约

public AlipayUserAgreementUnsignResponse aliPayUnSign(AliPayBo bo) { AlipayClient alipayClient = oldAliPayConfig.initAliPayClient(); AlipayUserAgreementUnsignRequest request = new AlipayUserAgreementUnsignRequest(); Map requestMap = new HashMap(); requestMap.put("personal_product_code","CYCLE_PAY_AUTH_P"); requestMap.put("sign_scene",AliPayConstant.SIGN_SCENE); requestMap.put("external_agreement_no",bo.getExternalAgreementNo()); String requestJson = JSONUtil.toJsonStr(requestMap); log.info("{}:周期扣款-解除签约入参:{}",bo.getExternalAgreementNo(),requestJson); request.setBizContent(requestJson); try { AlipayUserAgreementUnsignResponse response = alipayClient.execute(request); if (response.isSuccess()) { log.info("{}:周期扣款-解除签约,调用成功",bo.getExternalAgreementNo()); return response; }else { log.info("{}:周期扣款-解除签约,调用失败:{}",bo.getExternalAgreementNo(),response.getSubMsg()); } } catch (AlipayApiException e) { e.printStackTrace(); log.error("{}:周期扣款-解除签约,调用异常:{}",bo.getExternalAgreementNo(),e); } return null; }

以上,是先签约后代扣场景下应该会用到的接口,接口可以根据真实的业务场景,灵活组合到业务代码中,下面贴一下,我们业务的功能流程图,方便大家理解:

 定时任务,筛选上面建表中的,未支付的数据,进行轮询查询签约结果,然后进行扣款



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3