>  기사  >  위챗 애플릿  >  WeChat 개발 기업 결제 PHP 코드 구현

WeChat 개발 기업 결제 PHP 코드 구현

高洛峰
高洛峰원래의
2017-03-06 09:22:561767검색

이 글을 쓰는 목적은 주로 WeChat 공개 플랫폼에서 제공하는 SDK가 이 기능의 SDK 구현을 제공하지 않기 때문입니다.

사실 최종 구현은 여전히 ​​WeChat 공개 플랫폼 개발에 의존합니다. 문서와 SDK.

기업 결제 적용 시나리오: 공식 계정은 환불 처리, 금융 결제 등 팔로우한 사용자에게 지급합니다.

먼저 구현 아이디어에 대해 이야기하겠습니다.

SDK에 자동으로 설치 클래스 라이브러리를 기반으로 WxMchPay 컴포넌트를 확장하여 기업 결제 기능 확장을 실현합니다.

더 이상 고민하지 않고 코드를 살펴보겠습니다. 다음은 기업 결제를 구현하기 위해 SDK를 상속하는 구성 요소입니다.

$parameters 매개변수 참조: 기업 결제 API 문서

<?php
// 引入SDK
import(&#39;Common.Util.WxPay&#39;);

/**
 * 微信企业付款操作类
 * Author  :  Max.wen
 * DateTime: <15/9/16 11:00>
 */
class WxMchPay extends Wxpay_client_pub
{
    /**
     * API 参数
     * @var array
     * &#39;mch_appid&#39;         # 公众号APPID
     * &#39;mchid&#39;             # 商户号
     * &#39;device_info&#39;       # 设备号
     * &#39;nonce_str&#39;         # 随机字符串
     * &#39;partner_trade_no&#39;  # 商户订单号
     * &#39;openid&#39;            # 收款用户openid
     * &#39;check_name&#39;        # 校验用户姓名选项 针对实名认证的用户
     * &#39;re_user_name&#39;      # 收款用户姓名
     * &#39;amount&#39;            # 付款金额
     * &#39;desc&#39;              # 企业付款描述信息
     * &#39;spbill_create_ip&#39;  # Ip地址
     * &#39;sign&#39;              # 签名
     */
    public $parameters = [];

    public function __construct()
    {
        $this->url = &#39;https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers&#39;;
        $this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
    }

    /**
     * 生成请求xml数据
     * @return string
     */
    public function createXml()
    {
        $this->parameters[&#39;mch_appid&#39;] = WxPayConf_pub::APPID;
        $this->parameters[&#39;mchid&#39;]     = WxPayConf_pub::MCHID;
        $this->parameters[&#39;nonce_str&#39;] = $this->createNoncestr();
        $this->parameters[&#39;sign&#39;]      = $this->getSign($this->parameters);
        return $this->arrayToXml($this->parameters);
    }


    /**
     *     作用:使用证书,以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);
        //设置证书
        curl_setopt($ch,CURLOPT_CAINFO, WxPayConf_pub::SSLROOTCA_PATH);
        //使用证书:cert 与 key 分别属于两个.pem文件
        //默认格式为PEM,可以注释
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,&#39;PEM&#39;);
        curl_setopt($ch,CURLOPT_SSLCERT, WxPayConf_pub::SSLCERT_PATH);
        //默认格式为PEM,可以注释
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,&#39;PEM&#39;);
        curl_setopt($ch,CURLOPT_SSLKEY, 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;
        }
    }


}

컨트롤러 레이어 기능 구현:

<?php
/**
 * Author  :  Max.wen
 * DateTime: <15/9/20 16:47>
 */

namespace Home\Controller;


class TestController extends CommonController
{

    /**
     * 企业付款测试
     */
    public function rebate()
    {
        import(&#39;Common.Util.WxMchPay&#39;);
        $mchPay = new \WxMchPay();
        // 用户openid
        $mchPay->setParameter(&#39;openid&#39;, &#39;oy2lbszXkgvlEKThrzqEziKEBzqU&#39;);
        // 商户订单号
        $mchPay->setParameter(&#39;partner_trade_no&#39;, &#39;test-&#39;.time());
        // 校验用户姓名选项
        $mchPay->setParameter(&#39;check_name&#39;, &#39;NO_CHECK&#39;);
        // 企业付款金额  单位为分
        $mchPay->setParameter(&#39;amount&#39;, 100);
        // 企业付款描述信息
        $mchPay->setParameter(&#39;desc&#39;, &#39;开发测试&#39;);
        // 调用接口的机器IP地址  自定义
        $mchPay->setParameter(&#39;spbill_create_ip&#39;, &#39;127.0.0.1&#39;); # getClientIp()
        // 收款用户姓名
        // $mchPay->setParameter(&#39;re_user_name&#39;, &#39;Max wen&#39;);
        // 设备信息
        // $mchPay->setParameter(&#39;device_info&#39;, &#39;dev_server&#39;);

        $response = $mchPay->postXmlSSL();
        if( !empty($response) ) {
            $data = simplexml_load_string($response, null, LIBXML_NOCDATA);
            echo json_encode($data);
        }else{
            echo json_encode( array(&#39;return_code&#39; => &#39;FAIL&#39;, &#39;return_msg&#39; => &#39;transfers_接口出错&#39;, &#39;return_ext&#39; => array()) );
        }
    }
}

위 두 부분의 코드를 완성하면 기본적으로 기업 결제 API를 성공적으로 호출할 수 있습니다.

반환된 결과의 데이터 구조 예:

{
    "return_code": "SUCCESS",
    "return_msg": { },
    "mch_appid": "wx519cae424099ed6b",
    "mchid": "1228636402",
    "device_info": { },
    "nonce_str": "qjupk84q4iqxkb578hb5h2qiatgcwxwg",
    "result_code": "SUCCESS",
    "partner_trade_no": "test-1442801966",
    "payment_no": "1000018301201509210739170397",
    "payment_time": "2015-09-21 10:19:26"
}

가능한 문제:

1. CA 인증서 오류

WxMchPay에서 볼 수 있습니다. SDK의 Wxpay_client_pub의 postXmlSSLCurl() 메서드

왜냐하면 SDK의 이 메서드는 CURL POST 요청 시 기본적으로 CA 인증서와 함께 제공되지 않기 때문입니다.

이에 비해

curl_setopt($ch,CURLOPT_CAINFO, WxPayConf_pub::SSLROOTCA_PATH);  

  요청 시 CA 인증서를 첨부하는 기능입니다.

2. 동일한 사용자에게 전송 작업이 너무 자주 발생합니다. 나중에 다시 시도하세요.

이 오류는 WeChat의 한계에 속합니다. 서버, 특정 제한사항 빈도에 대한 설명은 없지만, 실제 테스트 후 1분 정도입니다.

그래서 개발할 때 더욱 주의를 기울여야 합니다.

WeChat 개발 기업 결제 PHP 코드 구현과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.