统一下单
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;
}
$data = array(
'appid' => config('mp.appid'),
'body' => '商城',
'mch_id' => config('mp.mch_id'),
'nonce_str' => self::getRandChar(32),
'notify_url' => '',
'out_trade_no' => $phone . '_' . time(),
'spbill_create_ip' => self::get_client_ip(),
'total_fee' => $total_fee,
'trade_type' => "JSAPI",
'openid' => $openid,
);
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$signkey = config('mp.key');
$data["sign"] = self::getSign($data, $signkey);
$xml = self::arrayToXml($data);
$response = self::postXmlCurl($xml, $url);
$ress = self::xmlstr_to_array($response);
if ($ress['return_code'] == 'FAIL') {
return array('code' => 0, 'message' => $ress['return_msg']);
}
if ($ress['result_code'] == 'FAIL') {
return array('code' => $ress['err_code'], 'message' => $ress['err_code_des']);
}
$datas = [
'appId' => config('mp.appid'),
'timeStamp' => time() . '',
'nonceStr' => self::getRandChar(32),
'package' => "prepay_id=" . $ress['prepay_id'],
'signType' => "MD5",
];
$datas['paySign'] = self::getSign($datas, $signkey);
$this->success('success', $datas);
}
private static function getRandChar($length)
{
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol) - 1;
for ($i = 0; $i < $length; $i++) {
$str .= $strPol[rand(0, $max)];
}
return $str;
}
private static function get_client_ip()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
private static function getSign($Obj, $api_key)
{
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
ksort($Parameters);
$String = self::formatBizQueryParaMap($Parameters, false);
$String = $String . "&key=" . $api_key;
$result = strtoupper(md5($String));
return $result;
}
private static function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
$reqPar;
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
private static function arrayToXml($arr)
{
$xml = "<xml>";
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
$xml .= "</xml>";
return $xml;
}
private static function postXmlCurl($xml, $url, $second = 30)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
echo "curl 出错,错误码:$error" . "<br>";
}
}
private static function xmlstr_to_array($xmlstr)
{
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xmlstr, 'SimpleXMLElement', LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring), true);
return $val;
}
支付成功回调
public function notify()
{
$testxml = file_get_contents("php://input");
$jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));
$result = json_decode($jsonxml, true);
file_log("mp_pay_notify_content.log", json_encode($result));
echo '<xml> <return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
}
微信小程序端
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,
nonceStr: result.nonceStr,
package: result.package,
signType: 'MD5',
paySign: result.paySign,
success(res) {
if (res.errMsg === 'requestPayment:ok') {
uni.navigateTo({
url: "/pages/index/order?phone=" + that.phone
})
}
},
fail(err) {
console.log("支付失败", err)
}
})
}
});