1
|
|
|
<?php |
2
|
|
|
namespace zhangv\wechat\pay\service; |
3
|
|
|
use \zhangv\wechat\pay\WechatPay; |
4
|
|
|
use \Exception; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* 企业付款 |
8
|
|
|
* @license MIT |
9
|
|
|
* @zhangv |
10
|
|
|
* @link https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1 |
11
|
|
|
* |
12
|
|
|
*/ |
13
|
|
|
class Mchpay extends WechatPay { |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* 企业付款到零钱 |
17
|
|
|
* @param $partner_trade_no |
18
|
|
|
* @param $openid |
19
|
|
|
* @param $amount |
20
|
|
|
* @param $desc |
21
|
|
|
* @param $spbill_create_ip |
22
|
|
|
* @param $check_name |
23
|
|
|
* @param $re_user_name |
24
|
|
|
* @return array |
25
|
|
|
* @throws Exception |
26
|
|
|
*/ |
27
|
2 |
|
public function transferWallet($partner_trade_no,$openid,$amount,$desc,$spbill_create_ip = null,$re_user_name = null,$check_name = WechatPay::CHECKNAME_FORCECHECK){ |
28
|
2 |
|
if($check_name == WechatPay::CHECKNAME_FORCECHECK && !$re_user_name) throw new Exception('Real name is required'); |
29
|
|
|
$data = [ |
30
|
2 |
|
"mch_appid" => $this->config["app_id"], |
31
|
2 |
|
"mchid" => $this->config["mch_id"], |
32
|
2 |
|
"partner_trade_no" => $partner_trade_no, |
33
|
2 |
|
"openid" => $openid, |
34
|
2 |
|
"amount" => $amount, |
35
|
2 |
|
"desc" => $desc, |
36
|
2 |
|
'spbill_create_ip' => $spbill_create_ip?:$_SERVER['SERVER_ADDR'], |
37
|
2 |
|
"check_name" => $check_name, |
38
|
2 |
|
"re_user_name" => $re_user_name |
39
|
|
|
]; |
40
|
2 |
|
return $this->post(self::URL_TRANSFER_WALLET,$data,true); |
|
|
|
|
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* 查询企业付款 |
45
|
|
|
* @param $partner_trade_no |
46
|
|
|
* @return array |
47
|
|
|
* @throws Exception |
48
|
|
|
*/ |
49
|
1 |
|
public function queryTransferWallet($partner_trade_no){ |
50
|
|
|
$data = [ |
51
|
1 |
|
"appid" => $this->config["app_id"], |
52
|
1 |
|
"mch_id" => $this->config["mch_id"], |
53
|
1 |
|
"partner_trade_no" => $partner_trade_no |
54
|
|
|
]; |
55
|
1 |
|
return $this->post(self::URL_QUERY_TRANSFER_WALLET,$data,true); |
|
|
|
|
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* 企业付款到银行卡 |
60
|
|
|
* @param $partner_trade_no |
61
|
|
|
* @param $bank_no |
62
|
|
|
* @param $true_name |
63
|
|
|
* @param $bank_code |
64
|
|
|
* @param $amount |
65
|
|
|
* @param $desc |
66
|
|
|
* @return array |
67
|
|
|
* @throws Exception |
68
|
|
|
*/ |
69
|
2 |
|
public function transferBankCard($partner_trade_no,$bank_no,$true_name,$bank_code,$amount,$desc){ |
70
|
2 |
|
if(!in_array($bank_code,array_values(self::$BANKCODE))) throw new Exception("Unsupported bank code: $bank_code"); |
71
|
|
|
$data = [ |
72
|
2 |
|
"partner_trade_no" => $partner_trade_no, |
73
|
2 |
|
"enc_bank_no" => $this->rsaEncrypt($bank_no), |
74
|
1 |
|
"enc_true_name" => $this->rsaEncrypt($true_name), |
75
|
1 |
|
"bank_code" => $bank_code, |
76
|
1 |
|
"desc" => $desc, |
77
|
1 |
|
"amount" => $amount |
78
|
|
|
]; |
79
|
1 |
|
return $this->post(self::URL_TRANSFER_BANKCARD,$data,true); |
|
|
|
|
80
|
|
|
} |
81
|
|
|
|
82
|
4 |
|
public function rsaEncrypt($data,$pubkey = null){ |
83
|
4 |
|
if(!$pubkey) $pubkey = $this->getPublicKey(); |
84
|
3 |
|
$encrypted = null; |
85
|
3 |
|
$pubkey = openssl_get_publickey($pubkey); |
86
|
3 |
|
if (@openssl_public_encrypt($data, $encrypted, $pubkey,OPENSSL_PKCS1_OAEP_PADDING)) |
87
|
2 |
|
$data = base64_encode($encrypted); |
88
|
|
|
else |
89
|
1 |
|
throw new Exception('Unable to encrypt data'); |
90
|
2 |
|
return $data; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* 查询企业付款银行卡 |
95
|
|
|
* @param $partner_trade_no |
96
|
|
|
* @return array |
97
|
|
|
* @throws Exception |
98
|
|
|
*/ |
99
|
1 |
|
public function queryTransferBankCard($partner_trade_no){ |
100
|
|
|
$data = [ |
101
|
1 |
|
"appid" => $this->config["app_id"], |
102
|
1 |
|
"mch_id" => $this->config["mch_id"], |
103
|
1 |
|
"partner_trade_no" => $partner_trade_no |
104
|
|
|
]; |
105
|
1 |
|
return $this->post(self::URL_QUERY_TRANSFER_WALLET,$data,true); |
|
|
|
|
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* 获取RSA加密公钥 |
110
|
|
|
* @param bool $refresh |
111
|
|
|
* @return string |
112
|
|
|
* @throws Exception |
113
|
|
|
*/ |
114
|
3 |
|
public function getPublicKey($refresh = false){ |
115
|
3 |
|
if(!$this->publicKey) { |
116
|
2 |
|
if (!$refresh && file_exists($this->config["rsa_pubkey_path"])) { |
117
|
1 |
|
$this->publicKey = file_get_contents($this->config["rsa_pubkey_path"]); |
118
|
|
|
}else{ |
119
|
2 |
|
$data = array(); |
120
|
2 |
|
$data["mch_id"] = $this->config["mch_id"]; |
121
|
2 |
|
$data["sign_type"] = $this->config["sign_type"]; |
122
|
2 |
|
$result = $this->post(self::URL_GETPUBLICKEY, $data, true); |
123
|
1 |
|
$pubkey = $result['pub_key']; |
124
|
1 |
|
$this->publicKey = $this->convertPKCS1toPKCS8($pubkey); |
125
|
1 |
|
if($fp = @fopen($this->config["rsa_pubkey_path"], "w")) { |
126
|
1 |
|
fwrite($fp, $this->publicKey); |
127
|
1 |
|
fclose($fp); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
} |
131
|
2 |
|
return $this->publicKey; |
132
|
|
|
} |
133
|
|
|
|
134
|
2 |
|
public function setPublicKey($publicKey){ |
135
|
2 |
|
$this->publicKey = $publicKey; |
136
|
2 |
|
} |
137
|
|
|
|
138
|
1 |
|
private function convertPKCS1toPKCS8($pkcs1){ |
139
|
1 |
|
$start_key = $pkcs1; |
140
|
1 |
|
$start_key = str_replace('-----BEGIN RSA PUBLIC KEY-----', '', $start_key); |
141
|
1 |
|
$start_key = trim(str_replace('-----END RSA PUBLIC KEY-----', '', $start_key)); |
142
|
1 |
|
$key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' . str_replace("\n", '', $start_key); |
143
|
1 |
|
$key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; |
144
|
1 |
|
return $key; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
} |