wxpay_native.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. /**
  3. * 微信扫码支付
  4. */
  5. class wxpay_native {
  6. /**
  7. * 支付信息初始化
  8. * @param array $payment_info
  9. */
  10. public function __construct($payment_info = array()) {
  11. if(!isset($payment_info['payment_config']['wx_appid'])){
  12. throw new \think\Exception('请配置微信支付', 10006);
  13. }
  14. define('WXN_APPID', $payment_info['payment_config']['wx_appid']);
  15. define('WXN_MCHID', $payment_info['payment_config']['wx_mch_id']);
  16. define('WXN_KEY', $payment_info['payment_config']['wx_key']);
  17. define('WXN_APPSECRET', $payment_info['payment_config']['wx_appsecret']);
  18. define('WXN_SSLCERT_PATH', $payment_info['payment_config']['wx_sslcert_path']);
  19. define('WXN_SSLKEY_PATH', $payment_info['payment_config']['wx_sslkey_path']);
  20. }
  21. /**
  22. * 组装包含支付信息的url(模式1) 失效
  23. */
  24. public function get_payforms() {
  25. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Api.php';
  26. require_once PLUGINS_PATH . '/payments/wxpay_native/WxPay.NativePay.php';
  27. require_once PLUGINS_PATH . '/payments/wxpay_native/log.php';
  28. $notify = new NativePay();
  29. return $notify->GetPrePayUrl($order_info['pay_sn']);
  30. }
  31. /**
  32. * 组装包含支付信息的url(模式2)
  33. */
  34. public function get_payform($order_info) {
  35. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Api.php';
  36. require_once PLUGINS_PATH . '/payments/wxpay_native/WxPay.NativePay.php';
  37. require_once PLUGINS_PATH . '/payments/wxpay_native/log.php';
  38. //统一下单
  39. $input = new WxPayUnifiedOrder();
  40. $input->SetBody(config('ds_config.site_name') . $order_info['pay_sn'] . '订单');
  41. $input->SetAttach($order_info['order_type']);
  42. $input->SetOut_trade_no($order_info['pay_sn'].'_'.TIMESTAMP);//31个字符,微信限制为32字符以内 TIMESTAMP 用来防止做随机数,用户支付订单后取消,已产生的订单不能重复支付
  43. $input->SetTotal_fee(bcmul($order_info['api_pay_amount'] , 100,0));
  44. $input->SetTime_start(date("YmdHis"));
  45. $input->SetTime_expire(date("YmdHis", TIMESTAMP + 3600));
  46. $input->SetGoods_tag('');
  47. $input->SetNotify_url(str_replace('/index.php', '', HOME_SITE_URL) . '/payment/wxpay_native_notify.html');
  48. $input->SetTrade_type("NATIVE");
  49. //$input->SetOpenid($openId);
  50. $input->SetProduct_id($order_info['pay_sn']);
  51. $result = WxPayApi::unifiedOrder($input);
  52. if(isset($result["code_url"])){
  53. return $result["code_url"];
  54. }else{
  55. halt($result);
  56. }
  57. }
  58. /**
  59. * 异步验证
  60. */
  61. public function verify_notify() {
  62. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Api.php';
  63. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Notify.php';
  64. $notify = new \WxPayNotify();
  65. $notify->Handle(true);
  66. $xml = file_get_contents('php://input');
  67. $data = $notify->FromXml($xml);
  68. if (!array_key_exists("transaction_id", $data)) {
  69. $verify_notify = false;
  70. } else {
  71. $transaction_id = $data['transaction_id'];
  72. $input = new \WxPayOrderQuery();
  73. $input->SetTransaction_id($transaction_id);
  74. $wxpay = new \WxPayApi();
  75. $result = $wxpay->orderQuery($input);
  76. if (array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") {
  77. $verify_notify = TRUE;
  78. } else {
  79. $verify_notify = false;
  80. }
  81. }
  82. if ($verify_notify) {
  83. $notify_result = array(
  84. 'out_trade_no' => $data["out_trade_no"], #商户订单号
  85. 'trade_no' => $data['transaction_id'], #交易凭据单号
  86. 'total_fee' => $data["total_fee"] / 100, #涉及金额
  87. 'order_type'=>$data["attach"],
  88. 'trade_status' => '1',
  89. );
  90. } else {
  91. $notify_result = array(
  92. 'trade_status' => '0',
  93. );
  94. }
  95. return $notify_result;
  96. }
  97. /**
  98. * 原路退款
  99. */
  100. public function trade_refund($order_info,$refund_amount)
  101. {
  102. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Api.php';
  103. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Notify.php';
  104. $order_model = model('order');
  105. $transaction_id = $order_info['trade_no'];
  106. //total_fee总订单价格 获取该支付单号所有的订单总额
  107. $fields = 'SUM(order_amount - rcb_amount - pd_amount) as total_fee';
  108. $condition = array();
  109. $condition[] = array('trade_no','=',$transaction_id);
  110. $tradeamount = $order_model->getOrderInfo($condition,array(),$fields);
  111. $total_fee = $tradeamount['total_fee'] * 100;
  112. $refund_fee = $refund_amount*100;
  113. $input = new WxPayRefund();
  114. $input->SetTransaction_id($transaction_id);
  115. $input->SetTotal_fee($total_fee);
  116. $input->SetRefund_fee($refund_fee);
  117. $input->SetOut_refund_no("sdkphp" . date("YmdHis"));
  118. $input->SetOp_user_id('');
  119. $wxpay = new \WxPayApi();
  120. $result = $wxpay->refund($input);
  121. if ($result['return_code'] == 'SUCCESS') {
  122. if ($result['result_code'] == 'SUCCESS') {
  123. return ds_callback(TRUE);
  124. } elseif ($result['err_code'] == 'NOTENOUGH') {//未结算资金不足时使用可用资金去退款
  125. $input->SetRefund_account('REFUND_SOURCE_RECHARGE_FUNDS');
  126. $result = $wxpay->refund($input);
  127. if ($result['return_code'] == 'SUCCESS') {
  128. if ($result['result_code'] == 'SUCCESS') {
  129. return ds_callback(TRUE);
  130. } else {
  131. return ds_callback(FALSE, $result['err_code_des']);
  132. }
  133. } else {
  134. return ds_callback(FALSE, $result['return_msg']);
  135. }
  136. } else {
  137. return ds_callback(FALSE, $result['err_code_des']);
  138. }
  139. } else {
  140. return ds_callback(FALSE, $result['return_msg']);
  141. }
  142. }
  143. /**
  144. * 转账
  145. */
  146. public function fund_transfer($withdraw_info)
  147. {
  148. require_once PLUGINS_PATH . '/payments/wxpay_native/lib/WxPay.Api.php';
  149. $inputObj = new WxPayResults();
  150. $inputObj->SetData('mch_appid', WxPayConfig::APPID);
  151. $inputObj->SetData('mchid', WxPayConfig::MCHID);
  152. $inputObj->SetData('nonce_str', WxPayApi::getNonceStr());
  153. $inputObj->SetData('partner_trade_no', $withdraw_info['pdc_sn']);
  154. $inputObj->SetData('openid', $withdraw_info['pdc_bank_no']);
  155. $inputObj->SetData('check_name', 'NO_CHECK');
  156. $inputObj->SetData('amount', $withdraw_info['pdc_amount']*100);
  157. $inputObj->SetData('desc', config('ds_config.site_name')."账户提现");
  158. $inputObj->SetData('spbill_create_ip', $_SERVER['REMOTE_ADDR']);
  159. $inputObj->SetSign();//签名
  160. $xml = $inputObj->ToXml();
  161. $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
  162. $startTimeStamp = WxPayApi::getMillisecond(); //请求开始时间
  163. $response = WxPayApi::postXmlCurl($xml, $url, true, 6);
  164. $obj=new WxPayResults();
  165. $result = $obj->FromXml($response);
  166. if($result['return_code'] == 'SUCCESS'){
  167. if($result['result_code'] == 'SUCCESS'){
  168. return ds_callback(TRUE,'',array('pdc_trade_sn'=>$result['payment_no']));
  169. }else{
  170. return ds_callback(FALSE, $result['err_code_des']);
  171. }
  172. }else{
  173. return ds_callback(FALSE, $result['return_msg']);
  174. }
  175. }
  176. }