微信新版代金券

微信代金券的注意事项
1.直连商户或者服务商需要登录微信商户后台开通预充值营销插件和免充值营销插件
2.公众账号的appid 与商户号关联绑定关系
3.小程序需要小程序appid与商户号关联绑定
4.需要服务商或者直连商户的cert证书的序列号key证书的在服务器的据对路径
5.如果是子商户发放服务商创建的代金券还需要子商户的cert证书与key证书在服务器的绝对路径,
6.子商户发放服务商创建的代金券还需要向微信发送邮件申请跨商户发券权限 :
Q:商户号A制券,允许商户号B发券,如何配置?(例如服务商制券,在子商户的场景例如公众号、小程序里发券)
A:跨商户号发券的使用场景是,A商户号制券,在B商户的场景中发券,例如小程序。需要A开通跨商户发券制券商户号的白名单、B开通商户发券发券商户号的白名单。然后A开始制券,制券是要把B添加为“可发券商户”。然后再用B的商户号调用接口,在和B商户号有绑定关系的APPID对应的场景中发券,就可以了。
目前申请流程:
需要先开通跨商户号发券权限。发邮件给v_jjinglliu@tencent.com,anthonylin@tencent.com,说明申请原因、制券的商户号、发券商户号。邮件标题“申请跨商户号发券+商户名称”。配置批次的时候把可发券商户号填发券商户,然后调用发券接口即可。申请后会在一个工作日内开通并回复邮件。
注意(需要把发券商户子商户放在批次的可发券商户号中)
7.创建代金券时no_cash 为true时是免充值类型,false为预充值类型
8.如果是服务商创建代金券时available_merchants 应该是可核销代金券的子商户集合
注意商户A制券B商户发放,服务商是没有分润,服务商制券,服务商发券这个是有分润的
9.公共类

<?php

namespace Addons\Pay;
class WxPayV3
{
    protected $authorization = 'WECHATPAY2-SHA256-RSA2048';  //认证类型
    protected $method = "POST";
    protected $url; //链接
    protected $mch_id;        //商户号
    protected $nonce_str;        //随机字符串
    protected $sign;        //签名
    protected $timestamp;   //时间
    protected $serial_no;        //商户Api证书序列号
    protected $apiclient_key;   //私钥地址
    protected $apiclient_cert;   //公钥地址
    protected $token;        //Token
    protected $data;         //发送参数
    protected $stock_id;     //批次号
    protected $response;    //返回信息
    protected $image_type;    //图片类型
    protected $boundary;      //边界符
    protected $suffix;      //图片后缀
    protected $openid;      //发放的openid
    protected $file;         //图片信息


    public function __construct($param)
    {
        $this->mch_id = isset($param['mch_id']) ? $param['mch_id'] : '';
        $this->data = isset($param['data']) ? $param['data'] : '';
        $this->stock_id = isset($param['stock_id']) ? $param['stock_id'] : '';
        $this->serial_no = isset($param['serial_no']) ? $param['serial_no'] : '';
        $this->apiclient_key = isset($param['apiclient_key']) ? $param['apiclient_key'] : '';
        $this->image_type = isset($param['image_type']) ? $param['image_type'] : '';
        $this->boundary = isset($param['boundary']) ? $param['boundary'] : '';
        $this->openid = isset($param['openid']) ? $param['openid'] : '';
        $this->file = isset($param['file']) ? $param['file'] : '';
    }


    /**
     * 上传图片
     * @return bool|string
     */
    public function upload()
    {
        $this->url = 'https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload';
        $result = $this->uploadRequestAction();
        return $result;
    }


    /**
     * 图片上传请求
     * @return bool|string
     */
    public function uploadRequestAction()
    {
        if (!in_array('sha256WithRSAEncryption', \openssl_get_md_methods(true))) {
            throw new \RuntimeException("当前PHP环境不支持SHA256withRSA");
        }
        $headerParam = $this->uploadHeaderParam(); //获取头部信息
        $boundarystr = "--{$this->boundary}\r\n";// $out是post的内容
        $str = $boundarystr;
        $str .= 'Content-Disposition: form-data; name="meta"' . "\r\n";
        $str .= 'Content-Type: application/json' . "\r\n";
        $str .= "\r\n";
        $str .= json_encode($this->data) . "\r\n";
        $str .= $boundarystr;
        $str .= 'Content-Disposition: form-data; name="file"; filename="' . $this->data['filename'] . '"' . "\r\n";
        $str .= 'Content-Type: ' . $this->image_type . ";\r\n";
        $str .= "\r\n";
        $str .= $this->file . "\r\n";
        $str .= $boundarystr . "--\r\n";
//        print_r($str);exit;
        $this->response = $this->http_Request($this->url, $headerParam, $str);
        return $this->response;
    }


    /**
     * 图片上传头部参数
     * @return array
     */
    public function uploadHeaderParam()
    {
        $this->getSign();        //生成签名
        $this->getToken();        //生成Token
        $header = [
            "Content-Type: multipart/form-data;name=meta",
            "Content-Type: application/json",
            "User-Agent:" . $_SERVER['HTTP_USER_AGENT'],
            'Authorization: ' . $this->authorization . ' ' . $this->token,
            "Content-Type: multipart/form-data;boundary=" . $this->boundary
        ];
        return $header;
    }


    /**
     * 创建代金券
     * @return bool|string
     */
    public function createCoupon()
    {
        $this->url = 'https://api.mch.weixin.qq.com/v3/marketing/favor/coupon-stocks';       //创建代金券请求链接
        $result = $this->requestAction();
        return $result;
    }


    /**
     * 激活代金券
     * @return bool|string
     */
    public function activateCoupon()
    {
        $this->url = "https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{$this->stock_id}/start";
        $result = $this->requestAction();
        return $result;
    }


    /**
     * 发放代金券
     */
    public function grant()
    {
        $this->url = "https://api.mch.weixin.qq.com/v3/marketing/favor/users/{$this->openid}/coupons";
        $result = $this->requestAction();
        return $result;
    }


    /**
     * 暂停代金券
     */
    public function suspend()
    {
        $this->url = "https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{$this->stock_id}/pause";
        $result = $this->requestAction();
        return $result;
    }


    /**
     * 重启代金券
     */
    public function restart()
    {
        $this->url = "https://api.mch.weixin.qq.com/v3/marketing/favor/stocks/{$this->stock_id}/restart";
        $result = $this->requestAction();
        return $result;
    }


    /**
     * 发送请求
     * @return bool|string
     */
    protected function requestAction()
    {
        if (!in_array('sha256WithRSAEncryption', \openssl_get_md_methods(true))) {
            throw new \RuntimeException("当前PHP环境不支持SHA256withRSA");
        }
        $headerParam = $this->getHeaderParam(); //获取头部信息
//       print_r($headerParam);
        $this->response = $this->http_Request($this->url, $headerParam, json_encode($this->data));
//        print_r(json_decode($this->response));
        return $this->response;
    }


    /**
     * 获取请求头部参数
     * @return array
     */
    protected function getHeaderParam()
    {
        $this->getSign();        //生成签名
        $this->getToken();        //生成Token
        $header = [
            "Content-type: application/json;charset='utf-8'",
            "Accept:application/json",
            "User-Agent:*/*",
            'Authorization: ' . $this->authorization . ' ' . $this->token,
        ];
        return $header;
    }


    /**
     * 生成签名
     */
    protected function getSign()
    {
        $url_parts = parse_url($this->url);  //链接
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $this->timestamp = time();
        $this->nonce_str = createKey(); //随机字符串
        $message = $this->method . "\n" .
            $canonical_url . "\n" .
            $this->timestamp . "\n" .
            $this->nonce_str . "\n" .
            json_encode($this->data) . "\n";
        openssl_sign($message, $raw_sign, openssl_get_privatekey(file_get_contents($this->apiclient_key)), 'sha256WithRSAEncryption');
        $this->sign = base64_encode($raw_sign);
    }


    /**
     * 生成Token
     * @return string
     */
    protected function getToken()
    {
        $this->token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $this->mch_id, $this->nonce_str, $this->timestamp, $this->serial_no, $this->sign);
    }


    /**
     * 数据请求
     * @param $url
     * @param array $header 获取头部
     * @param string $post_data POST数据,不填写默认以GET方式请求
     * @return bool|string
     */
    public function http_Request($url, $header = array(), $post_data = "")
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 2);
        if ($post_data != "") {
            curl_setopt($ch, CURLOPT_POST, TRUE);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); //设置post提交数据
        }
        //判断当前是不是有post数据的发
        $response = curl_exec($ch);
        if ($response === FALSE) {
            $response = "curl 错误信息: " . curl_error($ch);
        }
        curl_close($ch);
        return $response;
    }


}

### 微信代金券核销方法 微信支付提供了详细的API用于处理代金券放、查询以及最重要的核销操作。对于希望集成这些功能的应用程序来说,理解并正确调用微信支付提供的接口至关重要。 #### 接口概述 为了完成一次成功的代金券核销,开者应当访问`微信支付-批次核销明细下载 API`[^3]。此API允许商家获取特定时间段内的代金券使用情况报告,这对于跟踪促销活动的效果非常有用。然而,具体的单张代金券核销则需调用其他专门设计为此目的的服务端接口。 #### 实现流程 当涉及到实际的代金券核销过程时,通常会遵循如下模式: 1. 商家接收到来自用户的付款请求,其中包含了待使用的代金券信息。 2. 应用服务器验证该代金券的有效性和适用范围。 3. 如果一切正常,则向微信支付平台送HTTP POST请求来执行核销动作。这一步骤涉及构建符合要求的数据包,并按照规定的方式生成签名以确保通信安全。 4. 成功响应后更新本地数据库记录此次交易详情;失败情况下依据错误码采取相应措施重试或者提示用户解决问题。 #### Java代码片段展示如何起核销请求 下面是一个简单的Java例子展示了怎样构造一个HTTPS POST请求去调用微信支付的代金券核销接口: ```java import java.io.OutputStream; import javax.net.ssl.HttpsURLConnection; public class CouponRedemption { public static void main(String[] args) throws Exception{ String url = "https://api.mch.weixin.qq.com/v3/marketing/favor/batches/{batch-id}/coupons/{coupon-code}"; HttpsURLConnection conn = (HttpsURLConnection)new URL(url).openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // 构建请求体 JSON 字符串, 包含必要的字段如商户(mch_id), 随机字符串(nonce_str),时间戳(timestamp)等. String jsonInputString = "{\"mch_id\":\"your_merchant_id\",\"nonce_str\":\"random_string\",\"timestamp\": \"current_timestamp\"}"; try(OutputStream os = conn.getOutputStream()){ byte[] input = jsonInputString.getBytes("utf-8"); os.write(input, 0, input.length); } int responseCode = conn.getResponseCode(); System.out.println("\nSending 'POST' request to URL : " + url); System.out.println("Response Code : " + responseCode); BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String output; StringBuffer response = new StringBuffer(); while ((output = in.readLine()) != null) { response.append(output); } in.close(); // 处理返回的结果... } } ``` 请注意,在真实环境中还需要考虑更多细节,比如设置超时时间、异常处理机制等等。此外,务必参照最新的[官方文档](https://pay.weixin.qq.com/wiki/doc/apiv3/apis/index.shtml)[^1] 来获得最准确的信息和技术支持。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值