php对接微信支付

1、接入前准备  根据微信支付官方文档指引

https://pay.weixin.qq.com/doc/v3/merchant/4012064918

        下载微信支付证书脚本

        composer exec CertificateDownloader.php -- -k ${9*****} -m ${******} -f ${********} -s         ${**********} -o ${D:\wx\crm\app\\wechat}

  • -k 9∗∗∗∗∗:这是一个选项参数,−�表示后面的值是指定的密钥。9∗∗∗∗∗:这是一个选项参数,−k表示后面的值是指定的密钥。{9*****}是一个占位符,实际是一个具体的密钥值。

  • -m ∗∗∗∗∗∗:这是另一个选项参数,−�表示后面的值是指定的模式。∗∗∗∗∗∗:这是另一个选项参数,−m表示后面的值是指定的模式。{******}是一个占位符,实际是一个具体的模式值。

  • -f ∗∗∗∗∗∗∗∗:这是一个选项参数,−�表示后面的值是指定的文件名。∗∗∗∗∗∗∗∗:这是一个选项参数,−f表示后面的值是指定的文件名。{********}是一个占位符,实际是一个具体的文件名。

  • -s ∗∗∗∗∗∗∗∗∗∗:这是一个选项参数,−�表示后面的值是指定的文件路径。∗∗∗∗∗∗∗∗∗∗:这是一个选项参数,−s表示后面的值是指定的文件路径。{**********}是一个占位符,实际上是一个具体的文件路径。

  • -o ParseError: KaTeX parse error: Undefined control sequence: \wx at position 4: {D:\̲w̲x̲\crm\app\\wecha…{D:\wx\crm\app\wechat}是一个占位符,实际是你自己要下载的地址

2、根据自己的开发语言下载对应的sdk包 (下面以php为示例,所有语言都类似)

composer require wechatpay/wechatpay

3、配置微信支付相关参数

     1:初始化

    private $merchantId; //商户号
    private $merchantPrivateKeyFilePath;
    private $merchantPrivateKeyInstance;
    private $merchantCertificateSerial;//证书序列号
    private $platformCertificateFilePath;
    private $platformPublicKeyInstance;
    private $platformCertificateSerial;
    private $instance;
    private $appId;
    private $apiKey;

    public function __construct()
    {
        //初始化配置
        try {
            $this->merchantId = env('WECHAT_MERID');
            $this->merchantCertificateSerial = env('WECHAT_MER_CERTIFICATE_SERIAL');
            $this->appId = env('SHOP_WECHAT_PAYMENT_APPID');
            $this->apiKey = env('WECHAT_APIKEY');
            // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
            $this->merchantPrivateKeyFilePath = 'file://' . dirname(dirname(__FILE__)) . '            自己私钥文件地址';
            $this->merchantPrivateKeyInstance = Rsa::from($this->merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
            // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
            $this->platformCertificateFilePath = 'file://' . dirname(dirname(__FILE__)) . 自己微信支付平台证书;
            $this->platformPublicKeyInstance   = Rsa::from($this->platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
            // 从「微信支付平台证书」中获取「证书序列号」
            $this->platformCertificateSerial = PemUtil::parseCertificateSerialNo($this->platformCertificateFilePath);
            // 构造一个 APIv3 客户端实例
            $this->instance = Builder::factory([
                'mchid'      => $this->merchantId,
                'serial'     => $this->merchantCertificateSerial,
                'privateKey' => $this->merchantPrivateKeyInstance,
                'certs'      => [
                    $this->platformCertificateSerial => $this->platformPublicKeyInstance,
                ],
            ]);
        } catch (\Exception $e) {
            throw new ApiException('此功能暂未开放,请稍后再试');
        }
    }

  2:发起微信支付

public function jsPay($outTradeNo,$goodsName,$totalFee,$openId,$orderType,$doneOrderType = 1){
         //自己回调时需要的参数会原样带回(非必填)
        $attach = json_encode([]);
       
        try {
            $body = [
                'json' => [
                    'mchid'        => $this->merchantId,
                    'out_trade_no' => "自己系统单号",
                    'appid'        => $this->appId,
                    'description'  => "订单描述",
                    'notify_url'   => "回调地址",
                    'amount'       => [
                        'total'    => 支付金额, (以分为单位)
                        'currency' => 'CNY'(人民币)
                    ],
                    'time_expire' => "",过期时间(具体时间格式看微信官方文档)
                    'payer' => [
                        'openid' => $openId,(支付人的openid)
                    ],
                    'attach' => $attach,
                ]
            ];

            $resp     = $this->instance
                ->chain('v3/pay/transactions/jsapi')
                ->post($body);

            $status =  $resp->getStatusCode();
            if ($status != 200){
                throw new ApiException($resp->getBody());
            }
            $body = json_decode($resp->getBody(),true);
            $data = $this->configForPayment($body['prepay_id']);(前端需要唤起微信支付组件的加密格式)
            return $data;
        } catch (\Exception $e) {
            // 进行错误处理
            throw new ApiException('支付异常,请稍后重试');
        }
    }

        3:支付回调

        

    public function notify($info)
    {
        Common::log('info','orderCallback',$info);
        $inWechatpaySignature = $info['wechatpay-signature'][0];
        $inWechatpayTimestamp = $info['wechatpay-timestamp'][0];
        $inWechatpaySerial    = $info['wechatpay-serial'][0];
        $inWechatpayNonce     = $info['wechatpay-nonce'][0];
        if ( !$inWechatpaySignature or !$inWechatpayTimestamp or !$inWechatpaySerial or !$inWechatpayNonce ) {
            header("Location:/404.html");
            exit;
        }
        $inBody   = file_get_contents("php://input");// 请根据实际情况获取,例如: file_get_contents('php://input');
        Common::log('info','refundsNotify inBody',json_decode($inBody,true));
        // 检查通知时间偏移量,允许5分钟之内的偏移
        $verifiedStatus   = Rsa::verify(
        // 构造验签名串
            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
            $inWechatpaySignature,
            $this->platformPublicKeyInstance
        );
        if ($verifiedStatus ) {
            // 转换通知的JSON文本消息为PHP Array数组
            $inBodyArray = (array) json_decode($inBody, true);
            // 使用PHP7的数据解构语法,从Array中解构并赋值变量
            [
                'resource' => [
                    'ciphertext'      => $ciphertext,
                    'nonce'           => $nonce,
                    'associated_data' => $aad
                ]
            ] = $inBodyArray;
            // 加密文本消息解密
            $inBodyResource = AesGcm::decrypt($ciphertext, $this->apiKey, $nonce, $aad);
            // 把解密后的文本转换为PHP Array数组
            $inBodyResourceArray = (array) json_decode($inBodyResource, true);
            $result = $inBodyResourceArray;
            Common::log('info','refundsNotify result',$result);
            if ( $result['trade_state'] == 'SUCCESS' ) {
                DB::beginTransaction();//开启事务
                try {

                    //写自己业务的回调逻辑                    

                    DB::commit();
                }catch (\Exception $exception){
                    DB::rollBack();
                    throw new ApiException($exception->getMessage());
                }
      
                return 'success';
            }
        }
    }

 

    public function configForPayment($prepayId)
    {
        $params = [
            'appId'     => $this->appId,
            'timeStamp' => (string) Formatter::timestamp(),
            'nonceStr'  => Formatter::nonce(),
            'package'   => 'prepay_id=' . $prepayId,
        ];
        $params += [
            'paySign'  => Rsa::sign(
                Formatter::joinedByLineFeed(...array_values($params)),
                $this->merchantPrivateKeyInstance
            ),
            'signType' => 'RSA'
        ];

        return $params;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值