jh-admin/addon/coupon/model/CouponWeChat.php

1120 lines
58 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* SaaSMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2019-2029 成都SAAS云科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.gobuysaas.com
* =========================================================
*/
namespace addon\coupon\model;
use addon\wechatpay\model\Config;
use addon\weapp\model\Config as weAppConfig;
use addon\wechatpay\model\V3;
use app\model\BaseModel;
use think\Exception;
/**
* Common: 卡卷 - 微信端操作【小程序&公众号】
* 代金券开发文档https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter9_1_1.shtml
*
* Author: wu-hui
* Time: 2023/06/13 10:27
* Class CouponWeChat
* @package addon\coupon\model
*/
class CouponWeChat extends BaseModel{
private $app;
private $siteId;
private $mchId;
private $subMchId;
private $payConfig;
// 偏移时间;单位(秒);由于卡卷开始使用时间不能低于当前时间,所以在开始时间计算后需要添加偏移时间,保证开始时间参数正确
private $offsetTime = 5;
// 微信卡卷相关消息通知地址
private $notifyUrl;
// 商户模式true=服务商模式false=普通模式
private $stortMode = false;
/**
* Common: 基本配置初始化
* Author: wu-hui
* Time: 2023/06/13 10:43
* CouponWeChat constructor.
* @param int|string $siteId 平台id
* @param string $source 渠道mini=小程序wechat=公众号
* @throws Exception
*/
public function __construct($siteId){
// 域名相关信息处理
$domainName = request()->domain();
$this->notifyUrl = $domainName . '/pay/notify/weChatCoupon';
// 平台id获取
$this->siteId = (int)$siteId;
if($this->siteId <= 0) throw new Exception('缺少必要字段site_id');
// 实例化请求数据
$this->app = $this->api();
}
/**
* Common: 请求配置
* Author: wu-hui
* Time: 2023/06/28 14:20
* @return V3
* @throws \app\exception\ApiException
*/
private function api(){
// 普通模式
$payConfig = (new Config())->getPayConfig($this->siteId)['data']['value'];
if($this->stortMode){
// 服务商模式
$subConfig = $payConfig;
$payConfig = config('wechat.ispPay');
$payConfig['v3_pay_signkey'] = $payConfig['v3_signkey'] ?? '';
$payConfig['sub_mch_id'] = $subConfig['mch_id'] ?? '';
$payConfig['sub_pay_signkey'] = $subConfig['pay_signkey'] ?? '';
$payConfig['sub_v3_pay_signkey'] = $subConfig['v3_pay_signkey'] ?? '';
}
$this->payConfig = $payConfig;
if($payConfig) {
$payConfig['site_id'] = $this->siteId;
$this->subMchId = $payConfig['mch_id'] ?? '';
return (new V3($payConfig));
}
}
/**
* Common: 发起请求
* Author: wu-hui
* Time: 2023/06/28 14:40
* @param String $api
* @param array $params
* @param String $type
* @return mixed
* @throws Exception
*/
private function requestApi(String $api,array $params,String $type = 'post'){
$result = $this->app->requestApi($api,$params,$type);
if($result['code'] == 0) return $result['data'];
else throw new Exception($result['message']);
}
/**
* Common: 商家券 —— 创建
* Author: wu-hui
* Time: 2023/06/29 15:59
* @param $data
* @return mixed
* @throws Exception
*/
public function storeAdd($data){
// 发布参数获取
$params = $this->storeAddParams($data);
// 发起请求
return $this->requestApi('v3/marketing/busifavor/stocks',$params);
}
/**
* Common: 商家券 —— 创建参数获取
* Author: wu-hui
* Time: 2023/06/29 15:57
* @param $data
* @return array
* @throws Exception
*/
private function storeAddParams($data){
$maxMoney = 10000000;// 金额限制 1千万满减券-优惠金额、消费门槛;折扣券-消费门槛)
// 商品可用描述 1=全部商品参与2=指定商品参与
$goodsName = $data['goods_type'] == 1 ? '全部商品参与' : '指定商品参与';
// 批次类型 reward=满减discount=折扣
$stockType = $data['type'] == 'reward' ? 'NORMAL' : 'DISCOUNT';
// 有效期时间信息获取 商家券有效期最长为1年
[$startTime,$endTime] = $this->storeAddParamsTime($data);
$startTimeText = date("c",$startTime);
$endTimeText = date("c",$endTime);
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
$appid = $weAppConfig['appid'];
$path = '/pages_market/goods/list';
// 判断:发放数量 & 领取数量
if((int)$data['count'] > 10000000 || (int)$data['count'] < 1) throw new Exception('发放数量应在1~1千万之间');
if((int)$data['max_fetch'] > 100) throw new Exception('每个用户可领取数量应在1~100之间');
// 凭据号
$outRequestNo = 'S'.date('YmdHi') . (string)rand(10000, 99999);
// 配置请求参数
$params = [
'stock_name' => $data['coupon_name'],// 批次名称字数上限为21个一个中文汉字/英文字母/数字均占用一个字数。
'belong_merchant' => $this->subMchId,// 批次归属商户号。
'goods_name' => $goodsName,// 用来描述批次在哪些商品可用会显示在微信卡包中。字数上限为15个
'stock_type' => $stockType,// 批次类型NORMAL=固定面额满减券DISCOUNT=折扣券EXCHANGE=换购券
// 核销规则
'coupon_use_rule' => [
// 券可核销时间
'coupon_available_time' => [
'available_begin_time' => $startTimeText,// 开始时间商家券有效期最长为1年 例如2015-03-20T13:29:35+08:00
'available_end_time' => $endTimeText,// 结束时间商家券有效期最长为1年 例如2015-05-20T13:29:35+08:00
],
// 核销方式OFF_LINE=线下滴码核销MINI_PROGRAMS=线上小程序核销PAYMENT_CODE=微信支付付款码核销SELF_CONSUME=用户自助核销(暂不支持)
'use_method' => 'MINI_PROGRAMS',
'mini_programs_appid' => $appid,// 小程序appiduse_method=MINI_PROGRAMS 必填
'mini_programs_path' => $path,// 小程序pathuse_method=MINI_PROGRAMS 必填
],
// 发放规则
'stock_send_rule' => [
'max_coupons' => (int)$data['count'],// 批次最大可发放个数限制;特殊规则:取值范围 1 ≤ value ≤ 1000000000
'max_coupons_per_user' => (int)$data['max_fetch'],// 用户最大可领个数用户可领个数每个用户最多100张券
'natural_person_limit' => TRUE,// 【否】是否开启自然人限制true=是false=否(默认)
'prevent_api_abuse' => TRUE,// 【否】可疑账号拦截true=是false=否(默认)
],
'out_request_no' => $outRequestNo,// 商户创建批次凭据号格式商户id+日期+流水号),商户侧需保持唯一性
// 【否】自定义入口 卡详情页面,可选择多种入口引导用户。
'custom_entrance' => [
// 【否】小程序入口
'mini_programs_info' => [
'mini_programs_appid' => $appid,// 商家小程序appid
'mini_programs_path' => $path,// 商家小程序path
'entrance_words' => '查看详情',// 入口文案字数上限为5个一个中文汉字/英文字母/数字均占用一个字数。
],
'code_display_mode' => 'QRCODE',//【否】code展示模式NOT_SHOW=不展示codeBARCODE=一维码QRCODE=二维码
],
// 券code模式WECHATPAY_MODE=系统分配MERCHANT_API=商户发放时接口指定券codeMERCHANT_UPLOAD=商户上传自定义code发券时系统随机选取上传的券code。
'coupon_code_mode' => 'WECHATPAY_MODE',
// 【否】事件通知配置 事件回调通知商户的配置
'notify_config' => [
'notify_appid' => $appid,// 【否】事件通知appid小程序or公众号的APPID不填则回调通知中涉及到用户身份信息的openid与unionid都将为空
],
];
// 根据 【批次类型】 配置使用规则
$atLeast = (int)((float)$data['at_least'] * 100);// 消费门槛(单位分)
if($atLeast > $maxMoney || $atLeast < 1) throw new Exception("消费门槛应在1元~1千万元之间");
if($stockType == 'NORMAL'){
// 固定面额满减券
$money = (int)((float)$data['money'] * 100);// 优惠金额(单位分)
if($money > $maxMoney || $money < 1) throw new Exception("优惠金额应在1元~1千万元之间");
$params['coupon_use_rule']['fixed_normal_coupon'] = [
'discount_amount' => $money,// 优惠金额,单位:分。取值范围 1 ≤ value ≤ 10000000
'transaction_minimum' => $atLeast,// 消费门槛,单位:分。特殊规则:取值范围 1 ≤ value ≤ 10000000
];
}else{
// 折扣券
$discount = (float)((float)$data['discount'] * 10);
if($discount <= 0 || $discount > 100) throw new Exception("折扣无效折扣应在0.1~9.9之间!");
$params['coupon_use_rule']['discount_coupon'] = [
'discount_percent' => $discount,// 折扣百分比例如86为八六折。
'transaction_minimum' => $atLeast,// 消费门槛,单位:分。特殊规则:取值范围 1 ≤ value ≤ 10000000
];
}
return $params;
// ---- 全部参数
/*$params = [
'stock_name' => '',// 批次名称字数上限为21个一个中文汉字/英文字母/数字均占用一个字数。
'belong_merchant' => '',// 批次归属于哪个商户。
'comment' => '',// 【否】仅配置商户可见用于自定义信息。字数上限为20个
'goods_name' => '',// 用来描述批次在哪些商品可用会显示在微信卡包中。字数上限为15个
'stock_type' => '',// 批次类型NORMAL=固定面额满减券DISCOUNT=折扣券EXCHANGE=换购券
// 核销规则
'coupon_use_rule' => [
// 券可核销时间
'coupon_available_time' => [
'available_begin_time' => '',// 开始时间格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE 商家券有效期最长为1年 例如2015-03-20T13:29:35+08:00
'available_end_time' => '',// 结束时间格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE 商家券有效期最长为1年 例如2015-05-20T13:29:35+08:00
'available_day_after_receive' => '',// 【否】生效后N天内有效,1=当天2=明天;以此类推。
'wait_days_after_receive' => '',// 领取后N天开始生效领取后立即生效则不填写第二天则填1以此类推最大不能超过30天
// 【否】固定周期时间段
'available_week' => [
'week_day' => '',//0代表周日1代表周一以此类推;当填写available_day_time时week_day必填
// 当天可用时间段 可以填写多个时间段最多不超过2个。
'available_day_time' => [
[
'begin_time' => '',// 当天可用开始时间 当天可用开始时间单位1代表当天0点0分1秒。
'end_time' => '',// 当天可用结束时间 当天可用结束时间单位86399代表当天23点59分59秒。
]
],
],
// 【否】无规律的有效时间段 多个无规律时间段,用户自定义字段。
'irregulary_avaliable_time' => [
[
'begin_time' => '',// 开始时间格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE 例2015-05-20T13:29:35+08:00
'end_time' => '',// 结束时间格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE 例2015-05-20T13:29:35+08:00
]
],
],
// 【否】固定面额满减券使用规则 stock_type为NORMAL时必填。
'fixed_normal_coupon' => [
'discount_amount' => '',// 优惠金额,单位:分。取值范围 1 ≤ value ≤ 10000000
'transaction_minimum' => '',// 消费门槛,单位:分。特殊规则:取值范围 1 ≤ value ≤ 10000000
],
// 【否】折扣券使用规则 stock_type为DISCOUNT时必填。
'discount_coupon' => [
'discount_percent' => '',// 折扣百分比例如86为八六折。
'transaction_minimum'=> '',// 消费门槛,单位:分。特殊规则:取值范围 1 ≤ value ≤ 10000000
],
// 【否】换购券使用规则 stock_type为EXCHANGE时必填
'exchange_coupon' => [
'exchange_price' => '',//单品换购价,单位:分。特殊规则:取值范围 0 ≤ value ≤ 10000000
'transaction_minimum' => '',// 消费门槛,单位:分。特殊规则:取值范围 0 ≤ value ≤ 10000000
],
// 核销方式OFF_LINE=线下滴码核销MINI_PROGRAMS=线上小程序核销PAYMENT_CODE=微信支付付款码核销SELF_CONSUME=用户自助核销(暂不支持)
'use_method' => 'MINI_PROGRAMS',
'mini_programs_appid' => '',// 小程序appiduse_method=MINI_PROGRAMS 必填
'mini_programs_path' => '',// 小程序pathuse_method=MINI_PROGRAMS 必填
],
// 发放规则
'stock_send_rule' => [
'max_coupons' => '',// 批次最大可发放个数限制;特殊规则:取值范围 1 ≤ value ≤ 1000000000
'max_coupons_per_user' => '',// 用户最大可领个数用户可领个数每个用户最多100张券
'max_coupons_by_day' => '',// 【否】单天发放上限个数stock_type=DISCOUNT或者stock_type=EXCHANGE取值范围 1 ≤ value ≤ 1000000000
'natural_person_limit' => '',// 【否】是否开启自然人限制true=是false=否(默认)
'prevent_api_abuse' => '',// 【否】可疑账号拦截true=是false=否(默认)
'transferable' => '',// 【否、未开放】是否允许转赠true=是false=否(默认)
'shareable' => '',// 【否、未开放】是否允许分享链接true=是false=否(默认)
],
'out_request_no' => '',// 商户创建批次凭据号格式商户id+日期+流水号),商户侧需保持唯一性
// 【否】自定义入口 卡详情页面,可选择多种入口引导用户。
'custom_entrance' => [
// 【否】小程序入口
'mini_programs_info' => [
'mini_programs_appid' => '',// 商家小程序appid
'mini_programs_path' => '',// 商家小程序path
'entrance_words' => '',// 入口文案字数上限为5个一个中文汉字/英文字母/数字均占用一个字数。
'guiding_words' => '',// 【否】引导文案字数上限为6个一个中文汉字/英文字母/数字均占用一个字数。
],
'appid' => '',// 【否】商户公众号appid可配置商户公众号从券详情可跳转至公众号用户自定义字段。
'hall_id' => '',// 【否】营销馆id
'store_id' => '',// 【否】可用门店id
'code_display_mode' => 'QRCODE',//【否】code展示模式NOT_SHOW=不展示codeBARCODE=一维码QRCODE=二维码
],
// 【否】样式信息 创建批次时的样式信息
'display_pattern_info' => [
'description' => '',// 【否】使用须知;用于说明详细的活动规则,会展示在代金券详情页。
'merchant_logo_url' => '',// 【否建议上传】商户logo大小需为120像素*120像素;支持JPG/JPEG/PNG格式且图片小于1M
'merchant_name' => '',//【否】商户名称展示上限12个字符。不支持商户自定义
'background_color' => '',//【否】背景颜色;使用微信指定颜色值,不能自定义
'coupon_image_url' => '',//【否】券详情图片1074像素*603像素图片大小不超过2M支持JPG/PNG格式
],
// 【否】视频号相关信息
'finder_info' => [
'finder_id' => '',// 视频号ID
'finder_video_id' => '',// 视频号视频ID
'finder_video_cover_image_url' => '',// 视频号封面图图片尺寸1074像素*603像素图片大小不超过2M支持JPG/PNG格式。
],
'coupon_code_mode' => '',// 券code模式WECHATPAY_MODE=系统分配MERCHANT_API=商户发放时接口指定券codeMERCHANT_UPLOAD=商户上传自定义code发券时系统随机选取上传的券code。
// 【否】事件通知配置 事件回调通知商户的配置
'notify_config' => [
'notify_appid' => '',// 【否】事件通知appid小程序or公众号的APPID不填则回调通知中涉及到用户身份信息的openid与unionid都将为空
],
'subsidy' => '',// 【否】是否允许营销补贴true=允许false=否(默认)
];*/
}
/**
* Common: 商家券 —— 创建参数 - 有效期时间参数获取
* Author: wu-hui
* Time: 2023/06/29 15:06
* @param $data
* @return array
*/
private function storeAddParamsTime($data):array{
// 0=固定时间1=领取之日起2=长期有效 商家券有效期最长为1年
$startTime = (int)(time() + $this->offsetTime);
switch((int)$data['validity_type']){
case 0:
// 固定时间
$maxEndTime = strtotime(date('Y-m-d H:i:s', $startTime)." +1 year");
$endTime = (int)$data['end_time'] > $maxEndTime ? $maxEndTime : (int)$data['end_time'];
break;
default:
$endTime = strtotime(date('Y-m-d H:i:s', $startTime)." +1 year");
}
return [$startTime,$endTime];
}
/**
* Common: 商家券 —— 查看详情
* Author: wu-hui
* Time: 2023/06/29 16:15
* @param $stockId
* @return mixed
* @throws Exception
*/
public function storeDetail($stockId){
// 请求参数配置
$params = [];
// 发起请求
return $this->requestApi("v3/marketing/busifavor/stocks/$stockId",$params,'get');
}
/**
* Common: 商家券 —— 核销用户券
* Author: wu-hui
* Time: 2023/07/10 16:50
* @param $stockId
* @param $couponCode
* @param $useRequestNo
* @param string $openId
* @return mixed
* @throws Exception
*/
public function storeMemberUse($stockId,$couponCode,$useRequestNo,$openId = ''){
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
// 发起请求
$params = [
'coupon_code' => $couponCode,// 券的唯一标识。
'stock_id' => $stockId,//微信为每个商家券批次分配的唯一ID
'appid' => $weAppConfig['appid'],// 支持小程序appid与公众号appid
'use_time' => date("c",time()),// 商户请求核销用户券的时间例如2015-05-20T13:29:35+08:00
'use_request_no' => $useRequestNo,// 每次核销请求的唯一标识,商户需保证唯一。
'openid' => $openId,// 【否】用户的唯一标识,做安全校验使用
];
return $this->requestApi("v3/marketing/busifavor/coupons/use",$params);
}
/**
* Common: 商家券 —— 根据过滤条件查询用户券
* Author: wu-hui
* Time: 2023/07/10 14:47
* @param $openid
* @param int $offset
* @param string $status
* @param int $stockId
* @return mixed
* @throws Exception
*/
public function storeMemberSelect($openid,int $offset = 0,string $status = '',int $stockId = 0){
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
// 请求参数配置
$params = [
'appid' => $weAppConfig['appid'],// 支持小程序appid与公众号appid
// 'stock_id' => $stockId,// 【否】微信为每个商家券批次分配的唯一ID是否指定批次号查询
// 'coupon_state' => '',// 【否】券状态SENDED=可用USED=已核销EXPIRED=已过期
'creator_merchant' => $this->subMchId,// 【否】批次创建方商户号,当调用方商户号(即请求头中的商户号)为创建批次方商户号时,该参数必传
// 'belong_merchant' => '',// 【否】批次归属商户号,当调用方商户号(即请求头中的商户号)为批次归属商户号时,该参数必传
// 'sender_merchant' => '',// 【否】批次发放商户号,当调用方商户号(即请求头中的商户号)为批次发放商户号时,该参数必传;委托营销关系下,请填写委托发券的商户号
'offset' => $offset,// 分页页码
'limit' => 20,// 分页大小
];
if($stockId > 0) $params['stock_id'] = $stockId;
if(!empty($status)) $params['coupon_state'] = $status;
// 发起请求
return $this->requestApi("v3/marketing/busifavor/users/$openid/coupons",$params,'get');
}
/**
* Common: 商家券 —— 查询用户单张券详情
* Author: wu-hui
* Time: 2023/07/10 15:05
* @param $openid
* @param string $couponCode
* @return mixed
* @throws Exception
*/
public function storeMemberSingleDetail($openid,string $couponCode){
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
$appid = $weAppConfig['appid'];// 支持小程序appid与公众号appid
// 发起请求
$params = [];
return $this->requestApi("v3/marketing/busifavor/users/$openid/coupons/$couponCode/appids/$appid",$params,'get');
}
/**
* Common: 商家券 —— 设置商家券事件通知地址
* Author: wu-hui
* Time: 2023/07/10 15:08
* @return mixed
* @throws Exception
*/
public function storeNotifySet(){
// 请求参数配置
$params = [
'mchid' => $this->subMchId,// 微信支付商户的商户号由微信支付生成并下发不填默认查询调用方商户的通知URL。
'notify_url' => $this->notifyUrl,// 商户提供的用于接收商家券事件通知的url地址必须支持https。
];
// 发起请求
return $this->requestApi("v3/marketing/busifavor/callbacks",$params);
}
/**
* Common: 商家券 —— 查询商家券事件通知地址
* Author: wu-hui
* Time: 2023/07/10 15:30
* @return mixed
* @throws Exception
*/
public function storeNotifySee(){
// 请求参数配置
$params = [
'mchid' => $this->subMchId,// 微信支付商户的商户号由微信支付生成并下发不填默认查询调用方商户的通知URL
];
// 发起请求
return $this->requestApi("v3/marketing/busifavor/callbacks",$params,'get');
}
/**
* Common: 商家券 —— 关联订单信息
* Author: wu-hui
* Time: 2023/07/10 15:43
* @param $stockId
* @param $couponCode
* @param $outTradeNo
* @return mixed
* @throws Exception
*/
public function storeOrderJoin($stockId,$couponCode,$outTradeNo){
$outRequestNo = 'COJ'.date('YmdHi') . (string)rand(10000, 99999);
// 请求参数配置
$params = [
'stock_id' => $stockId,// 微信为每个商家券批次分配的唯一ID对于商户自定义code的批次关联请求必须填写批次号
'coupon_code' => $couponCode,// 券的唯一标识
'out_trade_no' => $outTradeNo,// 微信支付下单时的商户订单号,欲与该商家券关联的微信支付
'out_request_no' => $outRequestNo,// 商户创建批次凭据号格式商户id+日期+流水号商户侧需保持唯一性可包含英文字母数字_*-等内容,不允许出现其他不合法符号。
];
// 发起请求
$result = $this->requestApi("v3/marketing/busifavor/coupons/associate",$params);
$result['out_request_no'] = $outRequestNo;
return $result;
}
/**
* Common: 商家券 —— 取消关联订单信息
* Author: wu-hui
* Time: 2023/07/10 16:05
* @param $stockId
* @param $couponCode
* @param $outTradeNo
* @param $outRequestNo
* @return mixed
* @throws Exception
*/
public function storeOrderJoinCancel($stockId,$couponCode,$outTradeNo,$outRequestNo){
// 请求参数配置
$params = [
'stock_id' => $stockId,// 微信为每个商家券批次分配的唯一ID对于商户自定义code的批次关联请求必须填写批次号
'coupon_code' => $couponCode,// 券的唯一标识
'out_trade_no' => $outTradeNo,// 微信支付下单时的商户订单号,欲与该商家券关联的微信支付
'out_request_no' => $outRequestNo,// 商户创建批次凭据号格式商户id+日期+流水号商户侧需保持唯一性可包含英文字母数字_*-等内容,不允许出现其他不合法符号。
];
// 发起请求
return $this->requestApi("v3/marketing/busifavor/coupons/disassociate",$params);
}
/**
* Common: 商家券 —— 修改批次预算
* Author: wu-hui
* Time: 2023/07/10 17:29
* @param $stockId
* @param $num
* @param $oldNum
* @param string $type
* @return mixed
* @throws Exception
*/
public function storeUpdateBudget($stockId,$num,$oldNum,$type = 'max'){
$modifyBudgetRequestNo = 'UB'.date('YmdHi') . (string)rand(10000, 99999);
// 请求参数配置
$params = [
'modify_budget_request_no' => $modifyBudgetRequestNo,// 修改预算请求单据号
];
// 根据修改类型进行处理 typemax=修改批次最大发放个数day=修改单天发放上限个数
if($type == 'max'){
$params['target_max_coupons'] = $num;// 批次最大发放个数 二选一
$params['current_max_coupons'] = $oldNum;// 当前批次最大发放个数当传入target_max_coupons大于0时current_max_coupons必传
}
else{
$params['target_max_coupons_by_day'] = $num;// 单天发放上限个数 二选一
$params['current_max_coupons_by_day'] = $oldNum;// 当前单天发放上限个数 当传入target_max_coupons_by_day大于0时current_max_coupons_by_day必填
}
// 发起请求
return $this->requestApi("v3/marketing/busifavor/stocks/$stockId/budget",$params,'patch');
}
/**
* Common: 商家券 —— 修改商家券基本信息(TODO未对接 - 目前商家券没有需要修改的内容所以暂不对接修改接口)
* Author: wu-hui
* Time: 2023/07/11 9:57
* @param $data
* @param $id
* @return mixed
* @throws Exception
*/
public function storeUpdateBaseInfo($data,$id){
$stockId = model('promotion_coupon_type')->getValue([
['coupon_type_id','=',$id]
],'weapp_stock_id');
// 发布参数获取
$params = $this->storeUpdateParams($data);
// 发起请求
return $this->requestApi("v3/marketing/busifavor/stocks/$stockId",$params,'patch');
}
/**
* Common: 商家券 —— 编辑参数获取(TODO未对接 - 目前商家券没有需要修改的内容所以暂不对接修改接口)
* Author: wu-hui
* Time: 2023/07/11 9:57
* @param $data
* @return array
*/
public function storeUpdateParams($data){
return [
// 【否】自定义入口 卡详情页面,可选择多种入口引导用户。
'custom_entrance' => [
// 【否】小程序入口
'mini_programs_info' => [
'mini_programs_appid' => '',// 商家小程序appid
'mini_programs_path' => '',// 商家小程序path
'entrance_words' => '查看详情',// 入口文案字数上限为5个一个中文汉字/英文字母/数字均占用一个字数。
'guiding_words' => '', // 小程序入口引导文案字数上限为6个一个中文汉字/英文字母/数字均占用一个字数。
],
'appid' => '',// 【否】可配置商户公众号,从券详情可跳转至公众号
'hall_id' => '',// 【否】填写微信支付营销馆的馆id用户自定义字段。 营销馆需在商户平台 创建
'code_display_mode' => 'QRCODE',//【否】code展示模式NOT_SHOW=不展示codeBARCODE=一维码QRCODE=二维码
],
'comment' => '',// 【否】批次备注,仅配置商户可见用于自定义信息。字数上限为20个
'goods_name' => '',// 【否】用来描述批次在哪些商品可用会显示在微信卡包中。字数上限为15个一个中文汉字/英文字母/数字均占用一个字数。
'out_request_no' => '',// 商户修改批次凭据号格式商户id+日期+流水号),商户侧需保持唯一性。
// 【否】样式信息 创建批次时的样式信息
'display_pattern_info' => [
'description' => '',// 【否】使用须知;用于说明详细的活动规则,会展示在代金券详情页。
'background_color' => '',//【否】背景颜色;使用微信指定颜色值,不能自定义
'coupon_image_url' => '',//【否】券详情图片1074像素*603像素图片大小不超过2M支持JPG/PNG格式
// 【否】视频号相关信息
'finder_info' => [
'finder_id' => '',// 视频号ID
'finder_video_id' => '',// 视频号视频ID
'finder_video_cover_image_url' => '',// 视频号封面图图片尺寸1074像素*603像素图片大小不超过2M支持JPG/PNG格式。
],
],
// 【否】核销规则
'coupon_use_rule' => [
// 核销方式OFF_LINE=线下滴码核销MINI_PROGRAMS=线上小程序核销PAYMENT_CODE=微信支付付款码核销SELF_CONSUME=用户自助核销(暂不支持)
'use_method' => 'MINI_PROGRAMS',
'mini_programs_appid' => '',// 小程序appiduse_method=MINI_PROGRAMS 必填
'mini_programs_path' => '',// 小程序pathuse_method=MINI_PROGRAMS 必填
],
// 【否】发放规则
'stock_send_rule' => [
'prevent_api_abuse' => '',// 【否】可疑账号拦截true=是false=否(默认)
],
// 【否】事件通知配置 事件回调通知商户的配置
'notify_config' => [
'notify_appid' => '',// 【否】事件通知appid小程序or公众号的APPID不填则回调通知中涉及到用户身份信息的openid与unionid都将为空
],
];
}
/**
* Common: 商家券 —— 申请退券
* Author: wu-hui
* Time: 2023/07/11 9:14
* @param $couponCode
* @param $stockId
* @return mixed
* @throws Exception
*/
public function storeRefund($couponCode,$stockId){
$returnRequestNo = 'CR'.date('YmdHi') . (string)rand(10000, 99999);
// 请求参数配置
$params = [
'coupon_code' => $couponCode,// 券的唯一标识
'stock_id' => $stockId,// 券的所属批次号
'return_request_no' => $returnRequestNo,// 每次退券请求的唯一标识,商户需保证唯一
];
// 发起请求
$result = $this->requestApi("v3/marketing/busifavor/coupons/return",$params);
$result['return_request_no'] = $returnRequestNo;
return $result;
}
/**
* Common: 商家券 —— 使券失效
* Author: wu-hui
* Time: 2023/07/11 9:23
* @param $couponCode
* @param $stockId
* @param string $reason
* @return mixed
* @throws Exception
*/
public function storeDeactivate($couponCode,$stockId,$reason = ''){
$returnRequestNo = 'CD'.date('YmdHi') . (string)rand(10000, 99999);
// 请求参数配置
$params = [
'coupon_code' => $couponCode,// 券的唯一标识
'stock_id' => $stockId,// 券的所属批次号
'deactivate_request_no' => $returnRequestNo,// 每次失效请求的唯一标识,商户需保证唯一
];
if(trim($reason)) $params['deactivate_reason'] = $reason;//失效的原因
// 发起请求
$result = $this->requestApi("v3/marketing/busifavor/coupons/deactivate",$params);
$result['deactivate_request_no'] = $returnRequestNo;
return $result;
}
/**
* Common: 代金券 —— 发布
* Author: wu-hui
* Time: 2023/06/28 14:32
* @param $data
* @return mixed
* @throws Exception
* @throws \app\exception\ApiException
*/
public function voucherAdd($data){
// 发布参数获取
$params = $this->voucherParams($data);
// 发起请求
return $this->requestApi('v3/marketing/favor/coupon-stocks',$params);
}
/**
* Common: 代金券 —— 发布 - 请求参数获取
* Author: wu-hui
* Time: 2023/06/27 14:01
* @param $data
* @return array
* @throws Exception
*/
private function voucherParams($data):array{
// 时间信息获取
[$startTime,$endTime] = $this->voucherParamsTime($data);
$startTimeText = date("c",$startTime);
$endTimeText = date("c",$endTime);
// 优惠劵发放数量
$count = (int)$data['count'];// 设置发放优惠劵数量
$maxCount = 10000000;
if($count < 5 || $count > $maxCount) throw new Exception('优惠劵发放数量必须大于5且小于等于1000万');
// 优惠劵面额和最高预算(单位:分) 面额-必须为整数、必须大于1元且小于等于500元
if((float)$data['money'] < 1 || (float)$data['money'] > 500) throw new Exception("优惠劵面额必须大于1元且小于等于500元");
$money = (int)((float)$data['money'] * 100);// 金额(单位分)
$maxMoney = (int)$money * $count;// 最高预算金额(单位分)
// 最大领取数量
$maxFetch = (int)$data['max_fetch'];
if($maxFetch < 1 || $maxFetch > 60 || $maxFetch > $count) throw new Exception('最大领取数量必须大于1且小于等于60且不能超过发放数量');
// 使用条件
$atLeast = (float)($data['at_least'] * 100);
if($atLeast <= $money) throw new Exception('使用条件金额必须大于优惠劵面额!');
// 凭据号
$outRequestNo = 'V'.date('YmdHi') . (string)rand(10000, 99999);
// 信息配置
$paramsConfig = [
'stock_name' => $data['coupon_name'],// * 批次名称批次名称最多9个中文汉字、最多20个字母、不能包含不当内容和特殊字符 _ , ; |
'belong_merchant' => $this->subMchId,// * 归属商户号
'available_begin_time' => $startTimeText,// * 批次开始时间开始时间不可早于当前时间、不能创建365天后开始的批次、批次可用时间范围最长为90天 例如2015-05-20T13:29:35+08:00
'available_end_time' => $endTimeText,// * 批次结束时间结束时间需晚于开始时间、可用时间最长为90天、有效时间间隔最短为1s 例如2015-05-20T13:29:35+08:00
// 批次使用规则
'stock_use_rule' => [
'max_coupons' => $count,// * 最大发券数发放总个数最少5个、发放总个数最多1000万个
'max_amount' => $maxMoney,// * 最大发券预算批次总预算最多1000万元 单位:分 max_amount需要等于coupon_amount面额 * max_coupons发放总上限
'max_coupons_per_user' => $maxFetch,// * 活动期间每个用户可领个数不能大于发放总个数、最少为1个最多为60个
'natural_person_limit' => true,// * 是否开启自然人限制;多个微信号同属于一个身份证时视为同一用户枚举值true 是、false 否
'prevent_api_abuse' => true,// * 是否开启防刷拦截;当用户命中恶意、小号、机器、羊毛党、黑产等风险行为时,无法成功发放代金券 是=true、否=false
],
// 代金券详情页
'pattern_info' => [
'description' => '微信支付营销代金券',// * 使用说明最多1000个UTF8字符
],
// 核销规则
'coupon_use_rule' => [
// 固定面额满减券使用规则 stock_type为NORMAL时必填。
'fixed_normal_coupon' => [
'coupon_amount' => $money,// 面额单位必须为整数、必须大于1元且小于等于500元
'transaction_minimum' => $atLeast,// 使用券金额门槛,单位:分;使用门槛必须大于优惠金额
],
'available_merchants' => [$this->subMchId],// 可用商户的交易才可核销/使用代金券
],
'no_cash' => true,// 营销经费。枚举值true免充值、false预充值
'stock_type' => 'NORMAL',// 批次类型仅支持NORMAL固定面额满减券批次
'out_request_no' => $outRequestNo,// 商户创建批次凭据号
];
if($data['goods_ids']) $paramsConfig['coupon_use_rule']['available_items'] = explode(',',$data['goods_ids']);
return $paramsConfig;
// ---- 全部参数
// $params = [
// 'stock_name' => '',// * 批次名称批次名称最多9个中文汉字、最多20个字母、不能包含不当内容和特殊字符 _ , ; |
// // 'comment' => '',// 批次备注批次备注最多60个UTF8字符数
// 'belong_merchant' => '',// * 归属商户号
// 'available_begin_time' => '',// * 批次开始时间开始时间不可早于当前时间、不能创建365天后开始的批次、批次可用时间范围最长为90天
// 'available_end_time' => '',// * 批次结束时间结束时间需晚于开始时间、可用时间最长为90天、有效时间间隔最短为1s
// // 批次使用规则
// 'stock_use_rule' => [
// 'max_coupons' => 0, // * 最大发券数发放总个数最少5个、发放总个数最多1000万个
// 'max_amount' => '', // * 最大发券预算批次总预算最多1000万元 单位:分 max_amount需要等于coupon_amount面额 * max_coupons发放总上限
// // 'max_amount_by_day' => 0, // 单天最大发券预算不能大于总预算、max_amount_by_day不可以为0
// 'max_coupons_per_user' => '',// * 活动期间每个用户可领个数不能大于发放总个数、最少为1个最多为60个
// 'natural_person_limit' => true,// *是否开启自然人限制;多个微信号同属于一个身份证时视为同一用户枚举值true 是、false 否
// 'prevent_api_abuse' => true,// *是否开启防刷拦截;当用户命中恶意、小号、机器、羊毛党、黑产等风险行为时,无法成功发放代金券 是=true、否=false
// ],
// // 代金券详情页
// 'pattern_info' => [
// 'description' => '',// * 使用说明最多1000个UTF8字符
// // 'merchant_logo' => '',// 商户logo商户logo 仅支持通过《图片上传API》接口获取的图片URL地址、商户logo大小需为120像素*120像素、支持JPG/JPEG/PNG格式且图片小于1M、最多128个UTF8字符
// // 'merchant_name' => '',// 品牌名称最多12个中文汉字、最多36个英文字符
// // 'background_color' => '',// 背景颜色色值需要参考卡券背景颜色图中的颜色值标识、不能直接使用RGB或者16位颜色值
// // 'coupon_image' => '',// 券详情图片850像素*350像素且图片大小不超过2M支持JPG/PNG格式仅支持通过《图片上传API》接口获取的图片URL地址。
// ],
// // 核销规则
// 'coupon_use_rule' => [
// // 允许指定券的特殊生效时间规则 - 该字段暂未开放
// /*'coupon_available_time' => [
// // 固定时间段可用
// 'fix_available_time' => [
// 'available_week_day' => '',// 允许指定每周固定星期数生效0代表周日生效1代表周一生效以此类推不填则代表在可用时间内周一至周日都生效。
// 'begin_time'=> '',// 当天开始时间
// 'end_time' => '',// 当天结束时间
// ],
// 'second_day_available' => '',// 领取后N天有效领取后券的开始时间为领券后第二天如7月1日领券那么在7月2日00:00:00开始true=是false=否
// 'available_time_after_receive' => '',// 领取后券的结束时间为领取N天后单位分钟
// ],*/
// // 固定面额满减券使用规则 stock_type为NORMAL时必填。
// 'fixed_normal_coupon' => [
// 'coupon_amount' => '',// 面额单位必须为整数、必须大于1元且小于等于500元
// 'transaction_minimum' => '',// 使用券金额门槛,单位:分;使用门槛必须大于优惠金额
// ],
// // 'goods_tag' => '',// 订单优惠标记按json格式最多允许录入50个、每个订单优惠标记支持字母/数字/下划线不超过128个UTF8字符
// // 'limit_pay' => '',// 指定付款方式;可指定零钱付款、指定银行卡付款,需填入支付方式编码、例如:[CFT,ICBC_CREDIT]
// // 指定银行卡bin付款的交易可核销/使用代金券,当批次限定了指定银行卡时方可生效
// /*'limit_card' => [
// 'name' => '',// 银行卡名称
// 'bin' => '',// 指定卡BIN;使用指定卡BIN的银行卡支付方可享受优惠按json格式 例如:['62123456','62123457']
// ],*/
// // 'trade_type' => [],// 允许指定支付方式的交易才可核销/使用不填则默认不限MICROAPP小程序支付、APPPAYAPP支付、PPAY免密支付、CARD刷卡支付、FACE人脸支付、OTHER其他支付
// // 'combine_use' => '',// 允许指定本优惠是否可以和本商户号创建的其他券同时使用不填则默认允许同时使用。枚举值true=是、false=否
// // 'available_items'=> '',// 可核销商品编码单个商品编码的字符长度为【1128】、条目个数限制为【150】
// // 'unavailable_items' => '',// 不可核销的商品编码或条目编码单个商品编码的字符长度为【1128】、条目个数限制为【150】
// 'available_merchants'=> '',// 可用商户的交易才可核销/使用代金券
// ],
// 'no_cash' => '',// 营销经费。枚举值true免充值、false预充值
// 'stock_type' => 'NORMAL',// 批次类型仅支持NORMAL固定面额满减券批次
// 'out_request_no' => '',// 商户创建批次凭据号
// // '商户创建批次凭据号' => [],// 扩展属性字段按json格式如无需要则不填写。
// ];
}
/**
* Common: 代金券 —— 发布 - 请求参数获取(时间参数处理)
* Author: wu-hui
* Time: 2023/06/27 11:16
* @param $data
* @return array
* @throws Exception
*/
private function voucherParamsTime($data):array{
switch((int)$data['validity_type']){
case 0:
// 固定时间
$startTime = (int)(time() + $this->offsetTime);
$maxEndTime = strtotime(date('Y-m-d H:i:s', $startTime)." +90 day");
$endTime = (int)$data['end_time'];
// 判断过期时间不能超出90天
if($endTime > $maxEndTime) throw new Exception('有效期错误微信代金券过期时间不能超过90天');
break;
case 1:
// 领取之日起
throw new Exception('有效期类型错误,微信代金券禁止使用该类型!');
break;
case 2:
// 长期有效
throw new Exception('有效期类型错误,微信代金券禁止使用该类型!');
break;
default:
throw new Exception('有效期类型错误,微信代金券禁止使用该类型!');
}
return [$startTime,$endTime];
}
/**
* Common: 代金券 —— 激活代金券批次
* Author: wu-hui
* Time: 2023/06/28 14:49
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherActivation($stockId){
// 参数获取
$params = [
'stock_creator_mchid' => $this->subMchId,// 批次创建方商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/start",$params);
}
/**
* Common: 代金券 —— 发放代金券批次
* Author: wu-hui
* Time: 2023/06/29 10:21
* @param $stockId
* @param $openid
* @return mixed
* @throws Exception
*/
public function voucherGrant($stockId,$openid){
// 生成凭据号
$outRequestNo = $this->subMchId.'NO'. (string)rand(10000, 99999);
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
// 参数获取
$params = [
'stock_id' => json_encode($stockId),// 批次id
'out_request_no' => $outRequestNo,// 商户此次发放凭据号
'appid' => $weAppConfig['appid'],// 小程序appid || 公众号appid || APP的appid
'stock_creator_mchid' => $this->subMchId,// 批次创建方商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/users/$openid/coupons",$params);
}
/**
* Common: 代金券 —— 暂停代金券批次
* Author: wu-hui
* Time: 2023/06/29 9:05
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherSuspend($stockId){
// 参数获取
$params = [
'stock_creator_mchid' => $this->subMchId,// 批次创建方商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/pause",$params);
}
/**
* Common: 代金券 —— 重启代金券批次
* Author: wu-hui
* Time: 2023/06/29 9:06
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherRestart($stockId){
// 参数获取
$params = [
'stock_creator_mchid' => $this->subMchId,// 批次创建方商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/restart",$params);
}
/**
* Common: 代金券 —— 条件查询批次列表
* Author: wu-hui
* Time: 2023/06/28 16:14
* @param int $offset
* @return mixed
* @throws Exception
*/
public function voucherBatchList(int $offset = 0){
// 参数获取
$params = [
'offset' => $offset,// 页码从0开始默认第0页
'limit' => 10,// 分页大小最大10
'stock_creator_mchid' => $this->subMchId,// 创建批次的商户号
// 'create_start_time' => '',// 起始创建时间 格式yyyy-MM-DDTHH:mm:ss+TIMEZONE 请求协议url编码
// 'create_end_time' => '',// 终止创建时间 格式yyyy-MM-DDTHH:mm:ss+TIMEZONE 请求协议url编码
// 'status' => '',// 批次状态unactivated=未激活audit=审核中running=运行中stoped=已停止paused暂停发放
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks",$params,'get');
}
/**
* Common: 代金券 —— 查询批次详情
* Author: wu-hui
* Time: 2023/06/29 9:10
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherBatchDetail($stockId){
// 参数获取
$params = [
'stock_creator_mchid' => $this->subMchId,// 批次创建方商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId",$params,'get');
}
/**
* Common: 代金券 —— 查询代金券详情
* Author: wu-hui
* Time: 2023/06/29 10:37
* @param $openid
* @param $couponId
* @return mixed
* @throws Exception
*/
public function voucherDetail($openid,$couponId){
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
// 参数获取
$params = [
'appid' => $weAppConfig['appid'],// 小程序appid || 公众号appid || APP的appid
];
// 发起请求
return $this->requestApi("v3/marketing/favor/users/$openid/coupons/$couponId",$params,'get');
}
/**
* Common: 代金券 —— 查询代金券可用商户
* Author: wu-hui
* Time: 2023/06/29 9:15
* @param $offset
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherAvailableMerchants($offset,$stockId){
// 参数获取
$params = [
'offset' => $offset,// 页码从0开始默认第0页
'limit' => 10,// 分页大小最大10
'stock_creator_mchid' => $this->subMchId,// 创建批次的商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/merchants",$params,'get');
}
/**
* Common: 代金券 —— 查询代金券可用单品
* Author: wu-hui
* Time: 2023/06/29 9:17
* @param $offset
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherAvailableGoods($offset,$stockId){
// 参数获取
$params = [
'offset' => $offset,// 页码从0开始默认第0页
'limit' => 10,// 分页大小最大10
'stock_creator_mchid' => $this->subMchId,// 创建批次的商户号
];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/items ",$params,'get');
}
/**
* Common: 代金券 —— 根据商户号查用户的券
* Author: wu-hui
* Time: 2023/06/29 10:33
* @param $offset
* @param $stockId
* @param $openid
* @return mixed
* @throws Exception
*/
public function voucherMemberCoupon($offset,$stockId,$openid){
// 获取配置信息
$weAppConfig = (new weAppConfig())->getWeappConfig($this->siteId)['data']['value'];
// 参数获取
$params = [
'appid' => $weAppConfig['appid'],// 公众账号ID
'stock_id' => $stockId,// 批次id
// 'status' => 'SENDED',//SENDED=返回可用,USED=返回可用+已实扣
'creator_mchid' => $this->subMchId,// 批次创建方商户号
'offset' => $offset,// 页码从0开始默认第0页
// 'limit' => 10,// 分页大小默认20
];
// 发起请求
return $this->requestApi("v3/marketing/favor/users/$openid/coupons",$params,'get');
}
/**
* Common: 代金券 —— 下载批次核销明细
* Author: wu-hui
* Time: 2023/06/29 10:42
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherDownloadBatchUseDetails($stockId){
// 参数获取
$params = [];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/use-flow",$params,'get');
}
/**
* Common: 代金券 —— 下载批次退款明细
* Author: wu-hui
* Time: 2023/06/29 10:48
* @param $stockId
* @return mixed
* @throws Exception
*/
public function voucherDownloadBatchRefundDetails($stockId){
// 参数获取
$params = [];
// 发起请求
return $this->requestApi("v3/marketing/favor/stocks/$stockId/refund-flow",$params,'get');
}
/**
* Common: 代金券 —— 设置消息通知地址;可接收营销相关的事件通知:核销通知
* Author: wu-hui
* Time: 2023/06/29 11:23
* @return mixed
* @throws Exception
*/
public function voucherSetNotify(){
// 参数获取
$params = [
'mchid' => $this->subMchId,
'notify_url' => $this->notifyUrl,
// 'switch' => true,// true=开启推送false=停止推送。 false暂不支持使用如果想关闭通知请在商户平台关闭券的回调通知
];
// 发起请求
return $this->requestApi("v3/marketing/favor/callbacks",$params);
}
/**
* Common: 获取微信优惠券领取信息
* Author: wu-hui
* Time: 2023/07/07 15:17
* @param $info
* @return array
*/
public function getWeAppConfig($info){
// 判断:如果没有配置信息 则返回空数组
if(!$this->payConfig) return [];
// 优惠券信息 每条信息代表领取一张卡券 一次最多可以领取10张
$outRequestNo = 'WEAPP'.date('YmdHi') . (string)rand(10000, 99999);
$sendCouponParams = [
[
'stock_id' => $info['weapp_stock_id'] ?? 0,//微信支付券批次id
'out_request_no' => $outRequestNo,//发券凭证可包含英文字母数字_*-等内容,不允许出现其他不合法符号,需在单个批次单个用户下确保唯一性
// 'create_coupon_merchant' => $this->subMchId,//创建支付券的商户号;如果是支付券,则是必填项;商家券无需填写
'customize_send_time' => date("c",time()),// 商家券在商户业务系统里的实际领取时间目前只支持商家券、支付券暂不支持。示例值2015-05-20T13:29:35+08:00
]
];
$key = $this->payConfig['pay_signkey'];
// 生成签名
$signArr = [];
foreach($sendCouponParams as $index => &$sendCouponParamsItem){
// 判断:如果是代金券 需要添加【create_coupon_merchant】字段内容如果是商家券则不需要该字段
if($info['weapp_channel'] == 'voucher') $sendCouponParamsItem['create_coupon_merchant'] = $this->subMchId;
// 循环处理 获取加密数组
foreach($sendCouponParamsItem as $sendCouponParamsKey => $subSendCouponParamsItem){
$signArr[$sendCouponParamsKey.$index] = $subSendCouponParamsItem;
}
}
$signArr['send_coupon_merchant'] = $this->subMchId;
ksort($signArr);
$signStr = urldecode(http_build_query($signArr))."&key=".$key;
$sign = strtoupper(hash_hmac("sha256", $signStr, $key));
return [
'send_coupon_params' => $sendCouponParams,
'sign' => $sign,//签名计算值 签名方式HMAC-SHA256。
'send_coupon_merchant' => $this->subMchId,//发券商户号
];
}
}