微信小程序支付v3

微信支付文档地址:微信支付-开发者文档
/**
 * 微信支付
 * 入参:
 * $openid:用户openid
 * $out_trade_no:商户订单号
 * $total_fee:订单金额(元)
 * $notify_url:支付回调地址
 **/
public function wxPay($openid,$notify_url,$out_trade_no,$total_fee)
{
    $config = Config::get('wechat');
    $appid = $config['app_id']; //小程序appid
    $merchantId = $config['mch_id']; // 商户号
    $merchantSerialNumber = $config['cert_serial']; // 商户API证书序列号
    $filepath = $config["APIv3_secret"]; //私钥在本地的位置

    //生成请求报文的主体
    $data = [
        "appid" => $appid,// 用户appid
        "mchid" => $merchantId,// 商户号
        "description" => '微信支付',//标题商品描述
        'out_trade_no' => $out_trade_no,//商户订单号
        'notify_url' => $notify_url,  //回调地址
        "amount" => [
            "total" => $total_fee*100,//订单金额(分)
            "currency" => "CNY"
        ],
        "payer" => [
            "openid" => $openid //用户openid
        ]
    ];
    $data = json_encode($data);

    //生成签名数据主体
    $timestamp = time();
    $nonce = date('YmdHis', time()) . rand(1000, 9999);
    $url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
    $url_parts = parse_url($url);
    $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
    $message = 'POST' . "\n" .
        $canonical_url . "\n" .
        $timestamp . "\n" .
        $nonce . "\n" .
        $data . "\n";

    //生成签名值
    $file = file_get_contents($filepath);//获取本地私钥
    $mch_private_key = openssl_get_privatekey($file);
    openssl_sign($message, $signature, $mch_private_key, "sha256WithRSAEncryption");
    $sign = base64_encode($signature);

    //对prepay_id再次签名的签名数据主体
    $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $merchantId, $nonce, $timestamp, $merchantSerialNumber, $sign);
    $header = "Authorization: WECHATPAY2-SHA256-RSA2048 " . $token;//token前面一定要有空格

    $res = $this->http_post($url, $header, $data);

    $arr = json_decode($res, true);
    $time = time();
    $str = time() . round('1000', '9999');
    $prepay = 'prepay_id=' . $arr['prepay_id'];

    $message1 = $appid . "\n" .
        $time . "\n" .
        $str . "\n" .
        $prepay . "\n";

    openssl_sign($message1, $signature, $mch_private_key, "sha256WithRSAEncryption");
    $sign1 = base64_encode($signature);


    $data = array();
    $data['timeStamp'] = $time;
    $data['nonce'] = $str;
    $data['prepay_id'] = $arr['prepay_id'];
    $data['sign'] = $sign1;

    return ['status' => 1, 'msg' => '操作成功', 'data' => $data];
}

微信回调文档地址:微信支付-开发者文档

//支付回调
public function notify()
{
    try {
        
        $mchkey= '';//商户平台设置的api v3 密码
        //获得内容
        $post = file_get_contents("php://input");
        //转数组
        $arr_post = json_decode($post,true);
        //解密
        $ciphertext = (new AesUtil($mchkey))->decryptToString($arr_post['resource']['associated_data'],$arr_post['resource']['nonce'],$arr_post['resource']['ciphertext']);
        $res = json_decode($ciphertext, true);

        if ($res['trade_state'] == 'SUCCESS') {
            //成功操作
            $data['out_trade_no'] = $res['out_trade_no'];
            $data['transaction_id'] = $res['transaction_id'];
            $data['openid'] = $res['payer']['openid'];
            $data['total_fee'] = $res['amount']['payer_total']/100;
            $data['success_time'] = strtotime($res['success_time']);
            test_log('微信支付回调成功:'.$str);
            return ['status' => 1, 'msg' => '操作成功', 'data' => $data];
        } else {
            test_log('微信支付回调失败1:'.$str);
            return ['status' => 0, 'msg' => '操作失败'];
        }
    }catch(\Exception $e){
        test_log('微信支付回调失败2:'.$e->getMessage());
        return ['status'=> 0, 'msg'=> '操作失败-'. $e->getMessage()];
    }
}
aesKey = $aesKey;
    }

    /**
     * Decrypt AEAD_AES_256_GCM ciphertext
     *
     * @param string $associatedData AES GCM additional authentication data
     * @param string $nonceStr AES GCM nonce
     * @param string $ciphertext AES GCM cipher text
     *
     * @return string|bool      Decrypted string on success or FALSE on failure
     * @throws \SodiumException
     */
    public function decryptToString($associatedData, $nonceStr, $ciphertext)
    {
        $ciphertext = \base64_decode($ciphertext);
        if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
            return false;
        }

        // ext-sodium (default installed on >= PHP 7.2)
        if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') &&
            \sodium_crypto_aead_aes256gcm_is_available()) {
            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey);
        }

        // ext-libsodium (need install libsodium-php 1.x via pecl)
        if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&
            \Sodium\crypto_aead_aes256gcm_is_available()) {
            return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey);
        }

        // openssl (PHP >= 7.1 support AEAD)
        if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
            $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
            $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);

            return \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr,
                $authTag, $associatedData);
        }

        throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
    }
}

你可能感兴趣的:(php,微信小程序,微信小程序,php)