微信转账提现接口实例

<?php
//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1);
//error_reporting(E_ALL);
require_once('vendor/autoload.php');
require_once('wxpay/data.php');
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Formatter;

class wxapiv3_model extends model
{
    protected $merchantId;
    protected $merchantPrivateKeyFilePath;
    protected $merchantPrivateKeyInstance;
    protected $merchantCertificateSerial;
    protected $platformCertificateFilePath;
    protected $platformPublicKeyInstance;
    protected $platformCertificateSerial;
    protected $apiv3Key;
    protected $wxpaydata;
    protected $config;

    public function __construct()
    {
        $this->wxpaydata = $wxpaydata;
        $this->config = $config;
        // 商户号
        $this->merchantId = '';
        // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
        $this->merchantPrivateKeyFilePath = 'file://'. APP_PATH .'/apiclient_key.pem';
        $this->merchantPrivateKeyInstance = Rsa::from($this->merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
        // 「商户API证书」的「证书序列号」
        $this->merchantCertificateSerial = '';
        // 从本地文件中加载「微信支付平台证书」(可使用证书下载工具得到),用来验证微信支付应答的签名
        $this->platformCertificateFilePath = 'file://'. APP_PATH .'/wechatpay.pem';
        $this->platformPublicKeyInstance = Rsa::from($this->platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
        // 从「微信支付平台证书」中获取「证书序列号」
        $this->platformCertificateSerial = PemUtil::parseCertificateSerialNo($this->platformCertificateFilePath);
        //APIv3密钥
        $this->apiv3Key = '';
    }

    public function createWXAPI()
    {
        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $this->merchantId,
            'serial'     => $this->merchantCertificateSerial,
            'privateKey' => $this->merchantPrivateKeyInstance,
            'certs'      => [
                $this->platformCertificateSerial => $this->platformPublicKeyInstance,
            ],
        ]);
        return $instance;
    }

    public function send($order)
    {
        $instance = $this->createWXAPI();
        try {
            $resp = $instance
                ->chain('/v3/fund-app/mch-transfer/transfer-bills')
                ->post([
                    'json' => [
                        'appid'       =>  $this->wxpaydata['appid'],
                        'out_bill_no' => $order['order_id'],
                        'transfer_scene_id' => $this->config['transfer_scene'],
                        'openid'  => $order['openid'],
                        'user_name'   => $this->encryptor($order['real_name']),
                        'transfer_amount' => (int)bcmul($order['order_price'], 100),
                        'transfer_remark'=> '积分提现',
                        //'notify_url' => $this->config['weburl'] . '/wxnotify.html',
                        'transfer_scene_report_infos' => [
                            [
                                'info_type' => '活动名称',
                                'info_content' => '新人注册送好礼'
                            ],
                            [
                                'info_type' => '奖励说明',
                                'info_content' => '现金奖励'
                            ]
                        ],
                    ],
                    'headers' => [
                        'Wechatpay-Serial' => $this->platformCertificateSerial,
                    ]]);

            $data = json_decode((string)$resp->getBody(), true);
            return array(
                'code' => $resp->getStatusCode(),
                'data' => $data,
                'msg' => ''
            );
        } catch (\Exception $e) {
            // 进行错误处理
            //$msg = $e->getMessage();
            //$code = $e->getCode();
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $r = $e->getResponse();
                $msg = json_decode((string)$r->getBody(), true);
                $code = $r->getStatusCode();
            }
            return array(
                'code' => $code,
                'msg' => $msg,
                'data' => ''
            );
        }
    }

    public function search($id){
        $instance = $this->createWXAPI();
        try {
            $resp = $instance
                ->chain("/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{$id}")
                ->get();

            $data = json_decode((string)$resp->getBody(), true);
            return array(
                'code' => $resp->getStatusCode(),
                'data' => $data,
                'msg' => ''
            );
        } catch (\Exception $e) {
            // 进行错误处理
            //$msg = $e->getMessage();
            //$code = $e->getCode();
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $r = $e->getResponse();
                $msg = json_decode((string)$r->getBody(), true);
                $code = $r->getStatusCode();
            }
            return array(
                'code' => $code,
                'msg' => $msg,
                'data' => ''
            );

        }
    }

    public function cancel($id){
        $instance = $this->createWXAPI();
        try {
            $resp = $instance
                ->chain("/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{$id}/cancel")
                ->post();

            $data = json_decode((string)$resp->getBody(), true);
            return array(
                'code' => $resp->getStatusCode(),
                'data' => $data,
                'msg' => ''
            );
        } catch (\Exception $e) {
            // 进行错误处理
            //$msg = $e->getMessage();
            //$code = $e->getCode();
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $r = $e->getResponse();
                $msg = json_decode((string)$r->getBody(), true);
                $code = $r->getStatusCode();
            }
            return array(
                'code' => $code,
                'msg' => $msg,
                'data' => ''
            );
        }
    }

    public function notify($inWechatpaySignature, $inWechatpayNonce, $inWechatpayTimestamp, $inBody)
    {
        // 检查通知时间偏移量,允许5分钟之内的偏移
        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
        $verifiedStatus = Rsa::verify(
        // 构造验签名串
            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
            $inWechatpaySignature,
            $this->platformPublicKeyInstance
        );
        if ($timeOffsetStatus && $verifiedStatus) {
            // 转换通知的JSON文本消息为PHP Array数组
            $inBodyArray = (array)json_decode($inBody, true);
            // 使用PHP7的数据解构语法,从Array中解构并赋值变量
            $ciphertext = $inBodyArray['resource']['ciphertext'];
            $nonce = $inBodyArray['resource']['nonce'];
            $aad = $inBodyArray['resource']['associated_data'];
            // 加密文本消息解密
            $inBodyResource = AesGcm::decrypt($ciphertext, $this->apiv3Key, $nonce, $aad);
            // 把解密后的文本转换为PHP Array数组
            $inBodyResourceArray = (array)json_decode($inBodyResource, true);
            return $inBodyResourceArray;
        }else{
            return false;
        }
    }

    public function encryptor($str)
    {
        return Rsa::encrypt($str, $this->platformPublicKeyInstance);
    }
}