php实现微信jsapi支付(v3版本)

统一下单
private $appid;
private $secret;
private $mch_id;
private $key;
private $serial_no;

const KEY_LENGTH_BYTE = 32;
const AUTH_TAG_LENGTH_BYTE = 16;

protected function _initialize()
{
    $this->appid = config('xj_mp.appid');//小程序appid
    $this->secret = config('xj_mp.secret');//小程序secret
    $this->mch_id = config('xj_mp.mch_id');//商户id
    $this->key = config('xj_mp.key');//v3key
    $this->serial_no = config('xj_mp.serial_no');//v3序列号
}
/**
     * 下单方法
     * @param   $params 下单参数
     */
    public function unifiedOrder($product_type = 1, $openid = '', $phone = '')
    {
        //订单总价
        $total_fee = 79900;
        if ($product_type == 1) {
            $total_fee = 79900;
        }
        if ($product_type == 2) {
            $total_fee = 99900;
        }
        $money = $total_fee;
        $url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
        $urlarr = parse_url($url);
        $appid = $this->appid;
        $mchid = $this->mch_id;;//
        $xlid = $this->serial_no;//秘钥序列号
        $data = [];
        $time = time();
        $data['appid'] = $appid;
        $data['mchid'] = $mchid;
        $data['description'] = '描述';//商品描述
        $data['out_trade_no'] = $phone . '_' . time() . '_xingji';//订单编号
        //$data['notify_url'] = $this->request->domain() . "/api/xjmpzl/notify";//回调接口 需根据自己的情况修改
        $data['notify_url'] = $this->request()->domain() . "api/xjmpzl/notify";//回调接口 需根据自己的情况修改
        //$money = 1;
        $data['amount']['total'] = $money;//金额 单位 分
        $data['payer']['openid'] = $openid;//用户openID
        $data = json_encode($data);
        $noncestr = $time;
        $key = $this->getSign($data, $urlarr['path'], $noncestr, $time);//签名
        $token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"', $mchid, $xlid, $noncestr, $time, $key);//头部信息
        $header = [
            'Content-Type:' . 'application/json; charset=UTF-8',
            'Accept:application/json',
            'User-Agent:*/*',
            'Authorization: WECHATPAY2-SHA256-RSA2048 ' . $token
        ];
        $ret = $this->curl_post_https($url, $data, $header);
        $ret = ltrim($ret, '{"prepay_id":"');
        $ret = rtrim($ret, '}"');
        //微信支付(小程序)签名
        $str = $this->getWechartSign($appid, time(), $noncestr, 'prepay_id=' . $ret);
        $arr = [
            'appId' => $appid,
            'timeStamp' => time() . "",
            'package' => 'prepay_id=' . $ret,
            'paySign' => $str,
            'nonceStr' => $noncestr . ""
        ];
        $this->success('success', $arr);
    }

    //微信支付签名
    public function getSign($data = [], $url, $randstr, $time)
    {
        $str = "POST" . "\n" . $url . "\n" . $time . "\n" . $randstr . "\n" . $data . "\n";
        $key = file_get_contents('apiclient_key.pem');//在商户平台下载的秘钥
        $str = $this->getSha256WithRSA($str, $key);
        return $str;
    }

    //调起支付的签名
    public function getWechartSign($appid, $timeStamp, $noncestr, $prepay_id)
    {
        $str = $appid . "\n" . $timeStamp . "\n" . $noncestr . "\n" . $prepay_id . "\n";
        $key = file_get_contents('apiclient_key.pem');
        $str = $this->getSha256WithRSA($str, $key);
        return $str;
    }

    public function getSha256WithRSA($content, $privateKey)
    {
        $binary_signature = "";
        $algo = "SHA256";
        openssl_sign($content, $binary_signature, $privateKey, $algo);
        $sign = base64_encode($binary_signature);
        return $sign;
    }

/* PHP CURL HTTPS POST */
public function curl_post_https($url, $data, $header)
{
   $action = curl_init();
   curl_setopt($action, CURLOPT_URL, $url);
   curl_setopt($action, CURLOPT_CONNECTTIMEOUT, 60);
   curl_setopt($action, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($action, CURLOPT_HEADER, 0);
   curl_setopt($action, CURLOPT_SSL_VERIFYPEER, 0);
   curl_setopt($action, CURLOPT_SSL_VERIFYHOST, 0);
   curl_setopt($action, CURLOPT_POST, 1);
   curl_setopt($action, CURLOPT_POSTFIELDS, $data);
   curl_setopt($action, CURLOPT_HTTPHEADER, $header);
   $result = curl_exec($action);
   curl_close($action);
   return $result;
}
    /**
     * 异步回调地址
     */
    public function notify()
    {	
    	//v3 回调需要解密 返回格式与V2也不相同
        //获取返回的xml
        $testxml = file_get_contents("php://input");
        //将xml转化为json格式
        //$jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));
        //转成数组
        $res = json_decode($testxml, true);
        $decode_data = $res['resource'];
        $associatedData = $decode_data['associated_data'];
        $nonceStr = $decode_data['nonce'];
        $ciphertext = $decode_data['ciphertext'];
        $ciphertext = \base64_decode($ciphertext);
        //解密
        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);
            $result = \openssl_decrypt($ctext, 'aes-256-gcm', $this->key, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData);
        }
        file_log("mp_pay_notify_content.log", $result);
        $result = json_decode($result,true);
        echo ' ';
    }
小程序端
			uni.request({
					url: '后端下单地址',
					method: 'GET',
					data: {
						product_type: this.product_type,
						openid: this.openid,
						phone: this.phone
					},
					success: (cts) => {
						var result = cts.data.data
						let that = this
						uni.requestPayment({
							appId: result.appId, // 公众号名称,由商户传入
							timeStamp: result.timeStamp, // 时间戳,自1970年以来的秒数
							nonceStr: result.nonceStr, // 随机串
							package: result.package,
							signType: 'RSA', // 微信签名方式:
							paySign: result.paySign, // 微信签名
							success(res) {
								if (res.errMsg === 'requestPayment:ok') {
									uni.navigateTo({
										url: "/pages/index/order?phone=" + that.phone
									})
								}
							},
							fail(err) {
								console.log("支付失败", err)
							}
						})

					}
				});

你可能感兴趣的:(PHP,Web前端,php,微信,开发语言)