Wxpay.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <?php
  2. namespace weixin;
  3. /**
  4. * @title : 微信支付API接口插件
  5. * @desc :
  6. * @Author : Rock
  7. * @Date : 2023-04-06 19:06:59
  8. */
  9. class Wxpay
  10. {
  11. protected $WxPayConfig=array();
  12. public function __construct()
  13. {
  14. $this->WxPayConfig=array(
  15. 'APPID'=>sysconfig('wchat.wxmini_user_appid'),//微信小程序/公众号APPID
  16. 'MCHID'=>sysconfig('wchat.wxmini_user_mchid'),//微信商户ID
  17. 'KEY'=>sysconfig('wchat.wxmini_user_paysecret'),//微信商户支付秘钥
  18. 'SSLCERT_PATH'=>dirname(__FILE__).'/cert/apiclient_cert.pem',//支付证书位置
  19. 'SSLKEY_PATH'=>dirname(__FILE__).'/cert/apiclient_key.pem',//支付证书秘钥位置
  20. 'NOTIFY_URL'=> $_SERVER['REQUEST_SCHEME']."://".$_SERVER['HTTP_HOST'].sysconfig('wchat.notify_url'),//支付结果通知
  21. 'wapurl' => sysconfig('wchat.wapurl'),//支付成功跳转地址
  22. );
  23. }
  24. /**
  25. * @title: 微信H5支付统一下单
  26. * @desc: 描述
  27. * @param {string} {oid} {} {订单号}
  28. * @param {string} {amount} {} {支付金额}
  29. * @param {string} {body} {} {支付说明}
  30. * @return {*}
  31. * @author: Rock
  32. * @method: POST
  33. * @Date: 2023-04-06 20:14:03
  34. */
  35. public function H5Pay($oid,$amount,$body='微信H5支付')
  36. {
  37. $wapurl=$this->WxPayConfig['wapurl'];
  38. $notify_url=$this->WxPayConfig['NOTIFY_URL'];
  39. $scene_info='{"h5_info":{"type": "wap","wap_url": "'.$wapurl.'","wap_name": "'.$body.'"}}';
  40. $nonce_str=GetRandStr(32); //创建随机码
  41. $URL='https://api.mch.weixin.qq.com/pay/unifiedorder'; //接口地址
  42. $order['appid']=$this->WxPayConfig['APPID']; //应用ID
  43. $order['mch_id']=$this->WxPayConfig['MCHID']; //商户号
  44. $order['device_info']='WEB'; //设备号
  45. $order['nonce_str']=$nonce_str; //随机字符串
  46. $order['sign_type']='MD5'; //签名类型
  47. $order['body']=$body; //商品描述
  48. $order['out_trade_no']=$oid; //商户订单号
  49. $order['total_fee']=$amount*100; //总金额
  50. $order['spbill_create_ip']=GetIP(); //终端IP
  51. $order['time_start']=date("YmdHis"); //交易起始时间
  52. $order['time_expire']=date("YmdHis", time() + 600); //交易结束时间
  53. $order['notify_url']=$notify_url; //通知地址
  54. $order['trade_type']='MWEB'; //交易类型
  55. $order['scene_info']=$scene_info; //交易场景信息
  56. $Sign_Data=$order;
  57. $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);//生成签名数据
  58. $order['sign']=$sign;
  59. $xml=Wxcommon::ToXml($order);
  60. $result=Wxcommon::postXmlCurl($xml,$URL); //POST方法发送XML请求
  61. $result=XmlToArray($result); //把返回结果转换成数组
  62. if(!isset($result['prepay_id'])){
  63. return $result['return_msg'];
  64. }
  65. $prepay_id=$result['prepay_id'];
  66. $trade_type=$result['MWEB'];
  67. WLog('WxPay_H5','请求:'.array2string($order));
  68. WLog('WxPay_H5','响应:'.array2string($result));
  69. if(isset($result['mweb_url'])){
  70. return $result['mweb_url'];
  71. }else{
  72. return $result['return_msg'];
  73. }
  74. }
  75. /**
  76. * @title: 微信扫码支付统一下单
  77. * @desc: 描述
  78. * @param {string} {oid} {} {订单号}
  79. * @param {string} {amount} {} {支付金额}
  80. * @param {string} {body} {} {支付备注}
  81. * @return {*}
  82. * @author: Rock
  83. * @method: POST
  84. * @Date: 2023-04-06 20:15:09
  85. */
  86. public function NativePay($oid,$amount,$body='微信扫码支付')
  87. {
  88. $notify_url=$this->WxPayConfig['NOTIFY_URL'];
  89. $nonce_str=GetRandStr(16); //创建随机码
  90. $URL='https://api.mch.weixin.qq.com/pay/unifiedorder'; //接口地址
  91. $order['appid']=$this->WxPayConfig['APPID']; //应用ID
  92. $order['mch_id']=$this->WxPayConfig['MCHID']; //商户号
  93. $order['device_info']='WEB'; //设备号
  94. $order['nonce_str']=$nonce_str; //随机字符串
  95. $order['sign_type']='MD5'; //签名类型
  96. $order['body']=$body; //商品描述
  97. $order['out_trade_no']=$oid; //商户订单号
  98. $order['total_fee']=$amount*100; //总金额
  99. $order['spbill_create_ip']=GetIP(); //终端IP
  100. $order['time_start']=(date("YmdHis")); //交易起始时间
  101. $order['time_expire']=(date("YmdHis", time() + 600)); //交易结束时间
  102. $order['notify_url']=$notify_url;
  103. $order['trade_type']='NATIVE'; //交易类型
  104. $Sign_Data=$order;
  105. $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']);//生成签名数据
  106. $order['sign']=$sign;
  107. $xml=Wxcommon::ToXml($order);
  108. $result=Wxcommon::postXmlCurl($xml,$URL);
  109. $result=XmlToArray($result);
  110. WLog('WxPay_Native','请求:'.$this->WxPayConfig['KEY'].array2string($order));
  111. WLog('WxPay_Native','响应:'.array2string($result));
  112. return $result;
  113. }
  114. /**
  115. * @title: 微信公众号/小程序支付统一下单
  116. * @desc: 描述
  117. * @param {string} {oid} {} {订单号}
  118. * @param {string} {amount} {} {支付金额}
  119. * @param {string} {openid} {} {用户OPENID}
  120. * @param {string} {body} {} {支付备注}
  121. * @return {*}
  122. * @author: Rock
  123. * @method: POST
  124. * @Date: 2023-04-06 20:16:34
  125. */
  126. public function JsApiPay($oid,$amount,$openid,$body='微信公众号支付')
  127. {
  128. $notify_url=$this->WxPayConfig['NOTIFY_URL'];
  129. $nonce_str=GetRandStr(32); //创建随机码
  130. $URL='https://api.mch.weixin.qq.com/pay/unifiedorder'; //接口地址
  131. $order['appid']=$this->WxPayConfig['APPID']; //应用ID
  132. $order['mch_id']=$this->WxPayConfig['MCHID']; //商户号
  133. $order['device_info']='WEB'; //设备号
  134. $order['nonce_str']=$nonce_str; //随机字符串
  135. $order['sign_type']='MD5'; //签名类型
  136. $order['body']=$body; //商品描述
  137. $order['out_trade_no']=$oid; //商户订单号
  138. $order['total_fee']=$amount*100; //总金额
  139. $order['spbill_create_ip']=GetIP(); //终端IP
  140. $order['time_start']=date("YmdHis"); //交易起始时间
  141. $order['time_expire']=date("YmdHis", time() + 600); //交易结束时间
  142. $order['notify_url']=$notify_url; //通知地址
  143. $order['trade_type']='JSAPI'; //交易类型
  144. $order['openid']=$openid;
  145. $Sign_Data=$order;
  146. $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']); //生成签名数据
  147. $order['sign']=$sign;
  148. $xml=Wxcommon::ToXml($order);
  149. $result=Wxcommon::postXmlCurl($xml,$URL);
  150. $result=XmlToArray($result);
  151. WLog('WxPay_JsApi','请求:'.array2string($order));
  152. WLog('WxPay_JsApi','响应:'.array2string($result));
  153. //开始公众号发起支付参数签名
  154. $nonce_str=GetRandStr(32);
  155. $arr['appId']=$this->WxPayConfig['APPID'];
  156. $arr['timeStamp']=''.time().'';
  157. $arr['nonceStr']=$nonce_str;
  158. if(!isset($result['prepay_id'])){
  159. return $result['return_msg'];
  160. }
  161. $arr['package']="prepay_id=".$result['prepay_id'];
  162. $arr['signType']="MD5";
  163. $sign=Wxcommon::MakeSign_MD5($arr,$this->WxPayConfig['KEY']);
  164. $arr['paySign']=$sign;
  165. WLog('WxPay_JsApi','JsApi发起参数:'.array2string($arr));
  166. return $arr;
  167. }
  168. /**
  169. * @title: 微信发红包
  170. * @desc: 描述
  171. * @param {string} {openid} {} {用户OPENID}
  172. * @param {string} {amount} {} {红包金额}
  173. * @param {string} {send_name} {} {商户名称}
  174. * @param {string} {wishing} {} {红包祝福语}
  175. * @param {string} {act_name} {} {活动名称}
  176. * @return {*}
  177. * @author: Rock
  178. * @method: POST
  179. * @Date: 2023-04-06 20:18:09
  180. */
  181. public function SendRedPack($openid,$amount,$send_name,$wishing="恭喜发财",$act_name='红包活动')
  182. {
  183. $nonce_str=GetRandStr(32); //创建随机码
  184. $mch_billno=time().mt_rand(1000000,9999999); //创建订单号
  185. $URL='https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack'; //接口地址
  186. $order['wxappid']=$this->WxPayConfig['APPID']; //应用ID
  187. $order['mch_id']=$this->WxPayConfig['MCHID']; //商户号
  188. $order['nonce_str']=$nonce_str; //随机字符串
  189. $order['re_openid']=$openid; //微信用户OPENID
  190. $order['send_name']=$send_name; //商户名称
  191. $order['wishing']=$wishing; //红包祝福语
  192. $order['act_name']=$act_name; //活动名称
  193. $order['mch_billno']=$mch_billno; //订单号
  194. $order['total_amount']=$amount*100; //总金额
  195. $order['total_num']=1; //红包人数
  196. $order['client_ip']=GetIP(); //IP地址
  197. $Sign_Data=$order; //生成签名数据
  198. $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']); //签名
  199. $order['sign']=$sign;
  200. $xml=Wxcommon::ToXml($order); //把参数转换成XML
  201. $SSLCERT_PATH =$this->WxPayConfig['SSLCERT_PATH'];
  202. $SSLKEY_PATH =$this->WxPayConfig['SSLKEY_PATH'];
  203. $result=Wxcommon::postXmlCurl($xml,$URL,$SSLCERT_PATH,$SSLKEY_PATH); //POST方法发送XML请求
  204. $result=XmlToArray($result); //把返回结果转换成数组
  205. WLog('WxSendRedPack_Request_Api','请求:'.array2string($order)); //记录发红包请求、返回结果日志
  206. WLog('WxSendRedPack_Request_Api','响应:'.array2string($result));
  207. return $result;
  208. }
  209. /**
  210. * @title: 微信支付退款
  211. * @desc: 描述
  212. * @param {string} {transaction_id} {} {支付流水号}
  213. * @param {float} {amount} {} {退款金额}
  214. * @param {float} {total} {} {订单总金额}
  215. * @param {string} {body} {} {退款备注}
  216. * @return {*}
  217. * @author: Rock
  218. * @method: POST
  219. * @Date: 2023-04-06 20:20:13
  220. */
  221. public function Refund($transaction_id,$amount,$total,$body='商品已售完')
  222. {
  223. $nonce_str=GetRandStr(32); //创建随机码
  224. $out_refund_no=time().mt_rand(1000000,9999999); //生成退款订单号
  225. $URL='https://api.mch.weixin.qq.com/secapi/pay/refund'; //接口地址
  226. $order['appid']=$this->WxPayConfig['APPID']; //应用ID
  227. $order['mch_id']=$this->WxPayConfig['MCHID']; //商户号
  228. $order['nonce_str']=$nonce_str; //随机字符串
  229. $order['sign_type']='MD5'; //签名类型
  230. $order['refund_desc']=$body; //退款原因
  231. $order['transaction_id']=$transaction_id; //退款交易号
  232. $order['out_refund_no']=$out_refund_no; //商户退款单号
  233. $order['total_fee']=$total*100; //总金额
  234. $order['refund_fee']=$amount*100; //退款金额
  235. $Sign_Data=$order;
  236. $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']); //生成签名数据
  237. $order['sign']=$sign;
  238. $xml=Wxcommon::ToXml($order);
  239. $SSLCERT_PATH =$this->WxPayConfig['SSLCERT_PATH'];
  240. $SSLKEY_PATH =$this->WxPayConfig['SSLKEY_PATH'];
  241. $result=Wxcommon::postXmlCurl($xml,$URL,$SSLCERT_PATH,$SSLKEY_PATH);
  242. $result=XmlToArray($result);
  243. WLog('WxRefund_Api','请求:'.array2string($order));
  244. WLog('WxRefund_Api','响应:'.array2string($result));
  245. return $result;
  246. }
  247. /**
  248. * @title: 微信打款接口
  249. * @desc: 描述
  250. * @param {*} $partner_trade_no
  251. * @param {*} $openid
  252. * @param {*} $amount
  253. * @param {*} $body
  254. * @return {*}
  255. * @author: Rock
  256. * @method: POST
  257. * @Date: 2023-04-06 20:21:32
  258. */
  259. public function Rransfers($partner_trade_no,$openid,$amount,$body='佣金打款')
  260. {
  261. $nonce_str=GetRandStr(32); //创建随机码
  262. $URL='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //接口地址
  263. $order['mch_appid']=$this->WxPayConfig['APPID']; //应用ID
  264. $order['mchid']=$this->WxPayConfig['MCHID']; //商户号
  265. $order['nonce_str']=$nonce_str; //随机字符串
  266. $order['openid']=$openid; //用户openid
  267. $order['check_name']='NO_CHECK'; //校验用户姓名选项
  268. $order['desc']=$body; //打款原因
  269. $order['partner_trade_no']=$partner_trade_no; //商户单号
  270. $order['amount']=$amount*100; //总金额
  271. $order['spbill_create_ip']=GetIP(); //Ip地址
  272. $Sign_Data=$order;
  273. $sign=Wxcommon::MakeSign_MD5($Sign_Data,$this->WxPayConfig['KEY']); //生成签名数据
  274. $order['sign']=$sign;
  275. $xml=Wxcommon::ToXml($order);
  276. $SSLCERT_PATH =$this->WxPayConfig['SSLCERT_PATH'];
  277. $SSLKEY_PATH =$this->WxPayConfig['SSLKEY_PATH'];
  278. $result=Wxcommon::postXmlCurl($xml,$URL,$SSLCERT_PATH,$SSLKEY_PATH);
  279. $result=XmlToArray($result);
  280. WLog('WxRransfers_Api','请求:'.array2string($order));
  281. WLog('WxRransfers_Api','响应:'.array2string($result));
  282. return $result;
  283. }
  284. /**
  285. * @title: 支付回调参数合法性校验
  286. * @desc: 描述
  287. * @param {*} $order
  288. * @return {*}
  289. * @author: Rock
  290. * @method: POST
  291. * @Date: 2023-04-06 20:21:52
  292. */
  293. public function Callback_SignCheck($order)
  294. {
  295. $sign=$order['sign'];
  296. unset($order['sign']);
  297. $sign2=Wxcommon::MakeSign_MD5($order,$this->WxPayConfig['KEY']);
  298. if($sign==$sign2){
  299. return true;
  300. }else{
  301. return false;
  302. }
  303. }
  304. /**
  305. * @title: 组装回调数据
  306. * @desc: 描述
  307. * @param {*} $status
  308. * @param {*} $msg
  309. * @return {*}
  310. * @author: Rock
  311. * @method: POST
  312. * @Date: 2023-04-06 20:22:10
  313. */
  314. public function Return_Result($status,$msg)
  315. {
  316. $data['return_code']=$status;
  317. $data['return_msg']=$msg;
  318. return Wxcommon::ToXml($data);
  319. }
  320. }
  321. ?>