Maison  >  Article  >  Applet WeChat  >  Explication détaillée des exemples de paiement par carte de crédit pour le développement des paiements WeChat

Explication détaillée des exemples de paiement par carte de crédit pour le développement des paiements WeChat

零下一度
零下一度original
2018-05-12 10:32:235859parcourir

Cet article présente le processus de développement du paiement par carte sous le paiement WeChat. Le paiement par carte WeChat fait référence au processus de paiement dans lequel l'utilisateur ouvre l'interface de glissement de carte du portefeuille WeChat, et le commerçant scanne le code QR et soumet le paiement pour finaliser le paiement.

微信支付开发(7) 刷卡支付0微信支付开发(7) 刷卡支付1

1. API de paiement par carte

Adresse d'interface

api.mch.weixin.qq.com/pay/micropay

Si un certificat est requis

Pas besoin.

Paramètres d'entrée

Nom nom de la variable type requis exemple de valeur description

wx88888888888888888 String(32)String(16) tr> tr>






ID de compte public appid est String(32)L'ID de compte public attribué par WeChat (le numéro d'entreprise corpid est cet appId)
Numéro de commerçant mch_id Oui String(32) 1900000109 Le numéro de commerçant attribué par le paiement WeChat
Numéro de l'appareil device_info Non String(32) 013467007045764 Terminal N° (personnalisé par le commerçant, tel que le numéro de magasin)
Chaîne aléatoire nonce_str Oui5K8264ILTKCH16CQ2502SI8ZNMTM67VS Chaîne aléatoire, ne dépassant pas 32 bits. Algorithme de génération de nombres aléatoires recommandé
Signature signe est String(32) C380BEC2BFD727A4B6845133519F3AD6 Signature, voir l'algorithme de génération de signature pour plus de détails
Description du produit corps Oui String(128) image image store-Shenzhen Tengda-QQ poupée Une brève description du produit Ce champ doit être renseigné strictement. conformément aux spécifications. Veuillez fournir des détails. Voir la réglementation des paramètres
Détails du produit Détail Non String(6000)






公众账号ID appid String(32) wx8888888888888888 微信分配的公众账号ID(企业号corpid即为此appId)
商户号 mch_id String(32) 1900000109 微信支付分配的商户号
设备号 device_info String(32) 013467007045764 终端设备号(商户自定义,如门店编号)
随机字符串 nonce_str String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
签名 sign String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
商品描述 body String(128) image形象店-深圳腾大- QQ公仔 商品简单描述,该字段须严格按照规范传递,具体请见参数规定
商品详情 detail String(6000)
{
"goods_detail":[
{
"goods_id":"iphone6s_16G",
"wxpay_goods_id":"1001",
"goods_name":"iPhone6s 16G",
"goods_num":1,
"price":528800,
"goods_category":"123456",
"body":"苹果手机"
},
{
"goods_id":"iphone6s_32G",
"wxpay_goods_id":"1002",
"goods_name":"iPhone6s 32G",
"quantity":1,
"price":608800,
"goods_category":"123789",
"body":"苹果手机"
}
]
}

商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。

goods_detail []:
└ goods_id String 必填 32 商品的编号
└ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号
└ goods_name String 必填 256 商品名称
└ goods_num Int 必填 商品数量
└ price Int 必填 商品单价,单位为分
└ goods_category String 可选 32 商品类目ID
└ body String 可选 1000 商品描述信息

附加数据 attach String(127) 说明 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
商户订单号 out_trade_no String(32) 1217752501201407033233368018 商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
商品详情 detail String(8192) 与提交数据一致

实际提交的返回

订单金额 total_fee Int 888 订单总金额,单位为分,只能为整数,详见支付金额
货币类型 fee_type String(16) CNY 符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
终端IP spbill_create_ip String(16) 8.8.8.8 调用微信支付API的机器IP
商品标记 goods_tag String(32)   商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
指定支付方式 limit_pay String(32) no_credit no_credit--指定不能使用信用卡支付
授权码 auth_code String(128) 120061098828009406 扫码支付授权码,设备读取用户微信中的条码或者二维码信息

La liste détaillée des produits est au format Json. Veuillez vous assurer d'utiliser la balise CDATA pour protéger la chaîne de texte JSON avant. transmettre la signature.

<xml>
   <appid>wx2421b1c4370ec43b</appid>
   <attach>订单额外描述</attach>
   <auth_code>120269300684844649</auth_code>
   <body>刷卡支付测试</body>
   <device_info>1000</device_info>
   <goods_tag></goods_tag>
   <mch_id>10000100</mch_id>
   <nonce_str>8aaee146b1dee7cec9100add9b96cbe2</nonce_str>
   <out_trade_no>1415757673</out_trade_no>
   <spbill_create_ip>14.17.22.52</spbill_create_ip>
   <time_expire></time_expire>
   <total_fee>1</total_fee>
   <sign>C29DB7DB1FD4136B84AE35604756362C</sign>
</xml>
goods_detail [] :
└ Goods_id Chaîne Obligatoire 32 Numéro de produit
└ wxpay_goods_id Chaîne Facultatif 32 Numéro de produit unifié défini par le paiement WeChat
└ Goods_name Chaîne Obligatoire 256 Nom du produit
└ Goods_num Int Quantité de produit requise
└ price Int Prix unitaire du produit requis en cents
└ Goods_category String Facultatif 32 ID de catégorie de produit
└ body String Oui Sélectionnez 1 000 informations de description du produit

Données supplémentaires attacher Non String(127) Description Des données supplémentaires sont renvoyées telles quelles dans l'API de requête et la notification de paiement. Ce champ est principalement utilisé par les commerçants pour transmettre des données personnalisées pour les commandes
Commande du commerçant. number out_trade_no Oui String(32) 1217752501201407033233368018 Le numéro de commande dans le système marchand peut contenir des lettres de moins de 32 caractères. Pour d'autres instructions, veuillez consulter le numéro de commande du commerçant
Détails du produit détail Non String(8192) Conforme aux données soumises La déclaration réellement soumise

Montant de la commande total_fee Oui Int 888 Montant total de la commande, en cents , ne peut être qu'un nombre entier. Pour plus de détails, voir Montant du paiement
Type de devise fee_type NonCNY Un code à trois lettres conforme à la norme ISO4217. La valeur par défaut est RMB : CNY. Pour une liste d'autres valeurs, voir Type de devise.
IP du terminal spbill_create_ip est String(16) 8.8.8.8 IP de la machine appelant l'API de paiement WeChat
Étiquette de marchandises goods_tag Non td> String(32) Étiquette de produit, paramètre du bon ou de la fonction de remise instantanée, veuillez vous référer au bon ou à la remise instantanée pour plus de détails
Spécifiez le mode de paiement limit_pay Non String(32) no_credit no_credit --Spécifiez que le paiement par carte de crédit ne peut pas être utilisé
Code d'autorisation auth_code Oui String(128) 120061098828009406 Scannez le code d'autorisation de paiement et l'appareil lit les informations du code-barres ou du code QR dans le WeChat de l'utilisateur
Par exemple :







返回状态码 return_code String(16) SUCCESS SUCCESS/FAIL 
此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
返回信息 return_msg String(128) 签名失败 返回信息,如非空,为错误原因 
签名失败 
参数格式校验错误
Remarque : La valeur du paramètre peut être échappée avec XML et la balise CDATA est utilisée pour indiquer que les données ne seront pas analysées par l'analyseur XML. Résultat renvoyéNom Nom de la variable Obligatoire Type Exemple de valeur Description

当return_code为SUCCESS的时候,还会包括以下字段:

名称 变量名 必填 类型 示例值 描述







公众账号ID appid String(32) wx8888888888888888 调用接口提交的公众账号ID
商户号 mch_id String(32) 1900000109 调用接口提交的商户号
设备号 device_info String(32) 013467007045764 调用接口提交的终端设备号,
随机字符串 nonce_str String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 微信返回的随机字符串
签名 sign String(32) C380BEC2BFD727A4B6845133519F3AD6 微信返回的签名,详见签名生成算法
业务结果 result_code String(16) SUCCESS SUCCESS/FAIL
错误代码 err_code String(32) SYSTEMERROR 详细参见错误列表
错误代码描述 err_code_des String(128) 系统错误 错误返回的信息描述

当return_code 和result_code都为SUCCESS的时,还会包括以下字段:

名称 变量名 必填 类型 示例值 描述







用户标识 openid String(128) Y 用户在商户appid 下的唯一标识
是否关注公众账号 is_subscribe String(1) Y 用户是否关注公众账号,仅在公众账号类型支付有效,取值范围:Y或N;Y-关注;N-未关注
交易类型 trade_type String(16) MICROPAY 支付类型为MICROPAY(即扫码支付)
付款银行 bank_type String(16) CMC 银行类型,采用字符串类型的银行标识,值列表详见银行类型
货币类型 fee_type String(16) CNY 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
订单金额 total_fee Int 888 订单总金额,单位为分,只能为整数,详见支付金额
现金支付货币类型 cash_fee_type String(16) CNY 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
现金支付金额 cash_fee Int 100 订单现金支付金额,详见支付金额
微信支付订单号 transaction_id String(32) 1217752501201407033233368018 微信支付订单号
商户订单号 out_trade_no String(32) 1217752501201407033233368018 商户系统的订单号,与请求一致。
商家数据包 attach String(128) 123456 商家数据包,原样返回
支付完成时间 time_end String(14) 20141030133525 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则

举例如下:

<xml>
   <return_code><![CDATA[SUCCESS]]></return_code>
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
   <device_info><![CDATA[1000]]></device_info>
   <nonce_str><![CDATA[GOp3TRyMXzbMlkun]]></nonce_str>
   <sign><![CDATA[D6C76CB785F07992CDE05494BB7DF7FD]]></sign>
   <result_code><![CDATA[SUCCESS]]></result_code>
   <openid><![CDATA[oUpF8uN95-Ptaags6E_roPHg7AG0]]></openid>
   <is_subscribe><![CDATA[Y]]></is_subscribe>
   <trade_type><![CDATA[MICROPAY]]></trade_type>
   <bank_type><![CDATA[CCB_DEBIT]]></bank_type>
   <total_fee>1</total_fee>
   <coupon_fee>0</coupon_fee>
   <fee_type><![CDATA[CNY]]></fee_type>
   <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>
   <out_trade_no><![CDATA[1415757673]]></out_trade_no>
   <attach><![CDATA[订单额外描述]]></attach>
   <time_end><![CDATA[20141111170043]]></time_end>
</xml>

二、刷卡支付类实现

在微信支付原来的微信支付类文件中,仿照统一支付类的方式,添加刷卡支付类如下:

/**
 * 刷卡支付接口类
 */
class MicroPay_pub extends Wxpay_client_pub
{    
    function __construct() 
    {
        //设置接口链接
        $this->url = "https://api.mch.weixin.qq.com/pay/micropay";
        //设置curl超时时间
        $this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
    }
    
    /**
     * 生成接口参数xml
     */
    function createXml()
    {
        try
        {
            //检测必填参数
            if($this->parameters["out_trade_no"] == null){
                throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!"."<br>");
            }elseif($this->parameters["body"] == null){
                throw new SDKRuntimeException("缺少统一支付接口必填参数body!"."<br>");
            }elseif ($this->parameters["total_fee"] == null ) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!"."<br>");
            }elseif ($this->parameters["auth_code"] == null) {
                throw new SDKRuntimeException("缺少统一支付接口必填参数auth_code!"."<br>");
            }
               $this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
               $this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
               $this->parameters["spbill_create_ip"] = $_SERVER[&#39;REMOTE_ADDR&#39;];//终端ip        
            $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
            $this->parameters["sign"] = $this->getSign($this->parameters);//签名
            // var_dump($this->parameters);
            return  $this->arrayToXml($this->parameters);
        }catch (SDKRuntimeException $e)
        {
            die($e->errorMessage());
        }
    }
}

原有的基础类和请求类也列出如下:

/**
 * 所有接口的基类
 */
class Common_util_pub
{
    function __construct() {
    }

    function trimString($value)
    {
        $ret = null;
        if (null != $value) 
        {
            $ret = $value;
            if (strlen($ret) == 0) 
            {
                $ret = null;
            }
        }
        return $ret;
    }
    
    /**
     *     作用:产生随机字符串,不长于32位
     */
    public function createNoncestr( $length = 32 ) 
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {  
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
        }  
        return $str;
    }
    
    /**
     *     作用:格式化参数,签名过程需要使用
     */
    function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v)
        {
            if($urlencode)
            {
               $v = urlencode($v);
            }
            //$buff .= strtolower($k) . "=" . $v . "&";
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar;
        if (strlen($buff) > 0) 
        {
            $reqPar = substr($buff, 0, strlen($buff)-1);
        }
        return $reqPar;
    }
    
    /**
     *     作用:生成签名
     */
    public function getSign($Obj)
    {
        foreach ($Obj as $k => $v)
        {
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //echo &#39;【string1】&#39;.$String.&#39;</br>&#39;;
        //签名步骤二:在string后加入KEY
        $String = $String."&key=".WxPayConf_pub::KEY;
        //echo "【string2】".$String."</br>";
        //签名步骤三:MD5加密
        $String = md5($String);
        //echo "【string3】 ".$String."</br>";
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        //echo "【result】 ".$result_."</br>";
        return $result_;
    }
    
    /**
     *     作用:array转xml
     */
    function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
             if (is_numeric($val))
             {
                 $xml.="<".$key.">".$val."</".$key.">"; 

             }
             else
                 $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";  
        }
        $xml.="</xml>";
        return $xml; 
    }
    
    /**
     *     作用:将xml转为array
     */
    public function xmlToArray($xml)
    {        
        //将XML转为array        
        $array_data = json_decode(json_encode(simplexml_load_string($xml, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA)), true);        
        return $array_data;
    }

    /**
     *     作用:以post方式提交xml到对应的接口url
     */
    public function postXmlCurl($xml,$url,$second=30)
    {        
        //初始化curl        
           $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOP_TIMEOUT, $second);
        //这里设置代理,如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, &#39;8.8.8.8&#39;);
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        curl_close($ch);
        //返回结果
        if($data)
        {
            curl_close($ch);
            return $data;
        }
        else 
        { 
            $error = curl_errno($ch);
            echo "curl出错,错误码:$error"."<br>"; 
            echo "<a href=&#39;http://curl.haxx.se/libcurl/c/libcurl-errors.html&#39;>错误原因查询</a></br>";
            curl_close($ch);
            return false;
        }
    }

    /**
     *     作用:使用证书,以post方式提交xml到对应的接口url
     */
    function postXmlSSLCurl($xml,$url,$second=30)
    {
        $ch = curl_init();
        //超时时间
        curl_setopt($ch,CURLOPT_TIMEOUT,$second);
        //这里设置代理,如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, &#39;8.8.8.8&#39;);
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        //设置header
        curl_setopt($ch,CURLOPT_HEADER,FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
        //设置证书
        //使用证书:cert 与 key 分别属于两个.pem文件
        //默认格式为PEM,可以注释
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,&#39;PEM&#39;);
        curl_setopt($ch,CURLOPT_SSLCERT, dirname(__FILE__).WxPayConf_pub::SSLCERT_PATH);
        //默认格式为PEM,可以注释
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,&#39;PEM&#39;);
        curl_setopt($ch,CURLOPT_SSLKEY, dirname(__FILE__).WxPayConf_pub::SSLKEY_PATH);
        //post提交方式
        curl_setopt($ch,CURLOPT_POST, true);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
        $data = curl_exec($ch);
        //返回结果
        if($data){
            curl_close($ch);
            return $data;
        }
        else { 
            $error = curl_errno($ch);
            echo "curl出错,错误码:$error"."<br>"; 
            echo "<a href=&#39;http://curl.haxx.se/libcurl/c/libcurl-errors.html&#39;>错误原因查询</a></br>";
            curl_close($ch);
            return false;
        }
    }
    
    /**
     *     作用:打印数组
     */
    function printErr($wording=&#39;&#39;,$err=&#39;&#39;)
    {
        print_r(&#39;<pre class="brush:php;toolbar:false">&#39;);
        echo $wording."</br>";
        var_dump($err);
        print_r(&#39;
'); } } /** * 请求型接口的基类 */ class Wxpay_client_pub extends Common_util_pub { var $parameters;//请求参数,类型为关联数组 public $response;//微信返回的响应 public $result;//返回参数,类型为关联数组 var $url;//接口链接 var $curl_timeout;//curl超时时间 /** * 作用:设置请求参数 */ function setParameter($parameter, $parameterValue) { $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue); } /** * 作用:设置标配的请求参数,生成签名,生成接口参数xml */ function createXml() { $this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID $this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号 $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//签名 return $this->arrayToXml($this->parameters); } /** * 作用:post请求xml */ function postXml() { $xml = $this->createXml(); $this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout); return $this->response; } /** * 作用:使用证书post请求xml */ function postXmlSSL() { $xml = $this->createXml(); $this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout); return $this->response; } /** * 作用:获取结果,默认不使用证书 */ function getResult() { $this->postXml(); $this->result = $this->xmlToArray($this->response); return $this->result; } }

三、发起支付

在程序中,获得用户的授权码,并填入到$authcode参数中。授权码就是条码上的那一串18位纯数字,以10、11、12、13、14、15开头

其他参数则自动生成或者手动输入指定。

调用函数如下所示

        //全局引入微信支付类
        Vendor(&#39;Wxpay.WxPayPubHelper.WxPayPubHelper&#39;);
        //使用统一支付接口
        $microPay = new \MicroPay_pub();
        //设置统一支付接口参数
        $microPay->setParameter("body","方倍商户刷卡支付");//商品描述
        $microPay->setParameter("out_trade_no", "$out_trade_no");//商户订单号 
        $microPay->setParameter("total_fee", $total_fee);//总金额  
        $microPay->setParameter("auth_code", $authcode);//授权码

        //获取统一支付接口结果
        $microPayResult = $microPay->getResult();

        //3. 异常判断
        if (!isset($microPayResult["result_code"]) || ($microPayResult["result_code"] == "FAIL")) {
            $this->resRpcError(isset($microPayResult[&#39;result_code&#39;]) ? $microPayResult[&#39;err_code_des&#39;] : $microPayResult[&#39;return_msg&#39;], "21000");
        }

【相关推荐】

1. 微信公众号平台源码下载

2. 分享微信公众号开发刷卡支付的实例教程

3. 微信开发之微信支付

4. 详解微信小程序支付功能开发错误总结

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn