微信转账提现接口实例
<?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);
}
}