一、JSAPI支付产品、APP支付产品、小程序支付产品流程图
二、H5支付产品、Native支付产品
三、工厂父类抽象类代码开发
<?php
/*** 微信父类抽象类* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:33*/
namespace Payment\WechatPay;
abstract class WechatPaymentHandle
{/*** 下单* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:36* @ return mixed*/protected abstract function pay();/*** 查询* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:39* @ param $transactionId 原支付交易对应的微信订单号* @ return mixed*/protected abstract function transac($transactionId);/*** 退款* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:42* @ param $outRefundNo 退款单号* @ param $amount 退款额* @ param string $notifyUrl 异步通知地址* @ param string $transactionId 原支付交易对应的微信订单号,与$outTradeNo二选一* @ param string $outTradeNo 原支付交易对应的商户订单号,与$transactionId二选一* @ return mixed*/protected abstract function refunds($outRefundNo,$amount,$notifyUrl ='',$transactionId = '',$outTradeNo = '');
}
四、工厂通道选择类代码开发
<?php
/*** 微信支付工厂通道选择类* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:47*/
namespace Payment\WechatPay;
use app\BaseError;
use Payment\WechatPay\impl\JsApi;
class WechatPaymentFactory
{protected static $instance = null;//缓存实例protected $merchantId = null;// 商户号protected $merchantSerialNumber = null;// 商户API证书序列号protected $appid = null;// 公众号IDprotected $merchantPrivateKey = null;// 商户私钥protected $channelType = 0;//通道类型/*** 初始化资源*/public function __construct($type){$this->merchantId = config('pay.wechat.merchant_id');$this->appid = config('pay.wechat.app_id');$this->merchantSerialNumber = config('pay.wechat.merchant_serial_number');$file = file_get_contents('./wechatpay/apiclient_key.pem');$this->merchantPrivateKey = openssl_get_privatekey($file);// 读取商户秘钥self::$instance = null;$this->channelType = $type;}/*** 通道选择* User: 龙哥·三年风水* Date: 2024/9/19* Time: 14:34* @ param $url* @ param $data* @ return null|JsApi*/public function sendWechatPaymentHandle($url,$data){switch ((int)$this->channelType){case 1:$data['appid'] = $this->appid;$data['mchid'] = $this->merchantId;$authorization = $this->getSign($url,$data);self::$instance = new JsApi($url,$authorization,$data);break;case 2:break;case 3:break;case 4:break;case 5:break;default:self::$instance = null;throw new BaseError("未设置任何通道",50000,200);break;}return self::$instance;}/*** 生成签名* User: 龙哥·三年风水* Date: 2024/9/19* Time: 14:01* @ param $url* @ param $data* @ return string*/protected function getSign($url,$data){$timestamp = time();$nonce = alnum(12).date('YmdHis', $timestamp) . rand(1000, 9999);$url_parts = parse_url($url);$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));$data = json_encode($data);$message = 'POST' . "\n" .$canonical_url . "\n" .$timestamp . "\n" .$nonce . "\n" .$data . "\n";openssl_sign($message, $signature, $this->merchantPrivateKey, "sha256WithRSAEncryption");$sign = base64_encode($signature);$schema = 'WECHATPAY2-SHA256-RSA2048';$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $this->merchantId, $nonce, $timestamp, $this->merchantSerialNumber, $sign);return "Authorization: " . $schema . " " . $token;}/***销毁资源*/public function __destruct(){$this->merchantId = null;$this->appid = null;$this->merchantSerialNumber = null;$this->merchantPrivateKey = null;self::$instance = null;}
}
五、JsApi支付产品代码开发
<?php
/*** jsapi支付方式* User: 龙哥·三年风水* Date: 2024/9/19* Time: 14:12*/
namespace Payment\WechatPay\impl;
use Payment\WechatPay\WechatPaymentHandle;
use app\BaseError;
class JsApi extends WechatPaymentHandle
{protected $url = ''; //访问路径protected $header = ''; //头文件protected $data = []; //数据组/*** 初始化* @ param $url* @ param $header* @ param $data*/public function __construct($url,$header,$data){$this->url = $url;$this->header = $header;$this->data = $data;}/*** 下单* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:36* @ return mixed*/public function pay(){$res = http_post($this->url, $this->header, $this->data);$arr = json_decode($res, true);if(isset($arr['code'])) {$error['code'] = $arr['code'];$error['message'] = $arr['message'];$error['timestamp'] = time();$error['ip'] = get_client_ip();file_put_contents('native_pay.txt', json_encode($error) . PHP_EOL, FILE_APPEND);throw new BaseError($arr['message'], 50000, 200);}return $arr;}/*** 查询* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:39* @ param $transactionId 原支付交易对应的微信订单号* @ return mixed*/public function transac($transactionId){// TODO: Implement transac() method.}/*** 退款* User: 龙哥·三年风水* Date: 2024/9/19* Time: 11:42* @ param $outRefundNo 退款单号* @ param $amount 退款额* @ param string $notifyUrl 异步通知地址* @ param string $transactionId 原支付交易对应的微信订单号,与$outTradeNo二选一* @ param string $outTradeNo 原支付交易对应的商户订单号,与$transactionId二选一* @ return mixed*/public function refunds($outRefundNo, $amount, $notifyUrl = '', $transactionId = '', $outTradeNo = ''){// TODO: Implement refunds() method.}/****/public function __destruct(){$this->url = '';$this->header = '';$this->data = [];}
}
六、测试调用
public function index(){//定义参数$data['description'] = '运费钱';$data['out_trade_no'] = create_order();$data['time_expire'] = date('Y-m-d\TH:i:s\+08:00',time()+3600);$data['notify_url'] = 'http://www.baidu.com';$data['amount'] = ['total' => 100,'currency' => 'CNY'];$data['payer'] = ['openid' => 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o'];// 初始化通道$wechatPaymentFactory = new WechatPaymentFactory(1);// 选择实例$wechatPaymentHandle = $wechatPaymentFactory->sendWechatPaymentHandle('https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi',$data);$res = $wechatPaymentHandle->pay();var_dump($res);
}