两种模式
1.签约扣款
2.扣款后签约
依据业务需求使用了 扣款后签约
1.每次扣款不能超过100元 每期每个签约只能扣款一次
2.应用审核必须通过审核才能走通
审核过程中会有sign错误问题出现 应用通过就没问题了(耽误了基本一天排查该问题)
应用私钥和证书一定要弄对 不然很麻烦
想看支付宝接口情况 https://opensupport.alipay.com/support/tools/cloudparse/interface?ant_source=antsupport
支付宝文档:周期扣款 | 网页&移动应用
composer包:支付宝更多方便的插件 | Pay
PHP框架 laravel
主要逻辑
1. 支付接口 - 返回str字符串 客户端利用sdk拉起
2.支付回调接口 - 支付成功会回调地址
3.签约通知接口 - 支付接口sign_notify_url参数填写地址 签约成功会回调该地址
4.解约通知接口 - 商户主动解约-没有用到 用户主动解约 会请求应用网关 设置支付宝应用网关为该地址
脚本
后续扣款脚本 时间为下次扣款的时间 最小维度为7天 提前5天可以扣款
重试脚本 建议重试两次
更新时间重试脚本 超过扣款时间 请求更改签约日期接口
1.app支付
支付接口 返回加密str给客户端客户端使用sdk拉起支付宝 、统一支付接口新增agreement_sign_params 参数 alipay/payment
```
/** * 支付宝支付 * * @return \Illuminate\Http\JsonResponse * @throws \Throwable */ public function payment() { $user = getApiUser(); $type = request("type", 'setmeal');//setmeal 包时套餐 eachcost单次套餐 $setmeal_id = request("setmeal_id");// 套餐id $setmeal = db('vip_setmeal')->find($setmeal_id); if (!isset($setmeal)) { return json(4001, '请选择套餐'); } if (strpos($setmeal->channel, '1') === false) { return json(4001, '类型不正确'); } $price = $setmeal->money; $title = $setmeal->title; $days = 0; switch ($setmeal->date_type) { case 1: $vip = 'week'; $days = 7; break; case 2: $vip = 'onemonth'; $days = 30; break; case 3: $vip = 'month'; $days = 90; break; case 4: $vip = 'year'; break; case 5: $vip = 'oneyear'; break; case 6: $vip = 'perpetual'; break; default: $vip = ''; break; } switch ($type) { case 'setmeal': $title1 = "购买会员时长" . $title; $title = $user['name'] . "购买会员时长" . $title; break; case 'eachcost': $title1 = "购买次数" . $title; $title = $user['name'] . "购买次数" . $title; break; default: $title1 = "购买会员时长"; $title = $user['name'] . "购买会员时长"; break; } // 将返回字符串,供后续 APP 调用,调用方式不在本文档讨论范围内,请参考官方文档。 $orderno = Order::getOrderNum(); $other['num'] = $setmeal->num; $other['price'] = $price; $other['type'] = $type; $other['date'] = $vip; $other['is_new'] = 1; $other['setmeal_id'] = $setmeal_id; // 生成支付宝支付参数 $params = [ 'subject' => $title1, 'out_trade_no' => $orderno, 'total_amount' => $price, 'agreement_sign_params' => [ 'personal_product_code' => 'CYCLE_PAY_AUTH_P', 'sign_scene' => 'INDUSTRY|DIGITAL_MEDIA', 'external_agreement_no' => $orderno, 'access_params' => [ 'channel' => 'ALIPAYAPP' ], 'period_rule_params' => [ 'period_type' => 'DAY', 'period' => $days, 'execute_time' => Carbon::now()->addDays($days)->toDateString(), 'single_amount' => $price, ], 'sign_notify_url' => config('app.url') . '/api/alipay/agreement' ], ]; Log::channel('orders')->info($orderno . '-拉起支付-data:' . json_encode($params, JSON_UNESCAPED_UNICODE)); try { DB::beginTransaction(); // 获取支付宝支付信息 Pay::config(config('ypay.alipay_config')); $order_str = Pay::alipay()->app($params)->getBody()->getContents(); Log::channel('orders')->info($orderno . '-拉起成功-data:' . $order_str); // 保存订单信息 $order = Order::query()->create([ "user_id" => $user['id'], "title" => $title, "ordernum" => $orderno, "prepay_id" => '', "remark" => request('remark'), "money" => $price,