[摘要]本篇文章给大家带来的内容是关于微信小程序支付的流程问题解析(代码解析),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档...
本篇文章给大家带来的内容是关于微信小程序支付的流程问题解析(代码解析),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档搞一发。
* 注:使用的PHP,不过支付流程都是这样
开发前必读
主要流程
准备工具
申请小程序微信支付
拿到小程序微信支付的商户号及设置秘钥
注意:小程序就只需要这两步,如果是web的话还需要设置支付目录授权域名,文档里面也有写的:https://pay.weixin.qq.com/wik..
统一下单
官方文档:https://pay.weixin.qq.com/wik...
/**
* 统一订单
*/
public function unifiedorder(){
// 以下配置是必填项,如有其它需求请自行配置
$config = array(
'appid' => 'xxxxxxx',//这里是小程序appid
'mch_id' => 'xxxxxxx',//商户ID
'nonce_str' => $this->getNonceStr(),//随机字符串
'body' => '这里是测试 - 测试',//请按照文档要求填写合格名称
'out_trade_no' => time().$this->getNonceStr(2),//流水单号
'total_fee' => '20',//金额,分为单位,这里是0.2元
'spbill_create_ip' => '123.123.123.123',//当前IP
'notify_url' => 'http://xxxx.com',//请恕我愚昧,我没搞懂他有什么用
'trade_type' => 'JSAPI',//必须填写JSAPI
'openid' => 'xxxxxxxx'//当前用户的openid,在trade_type=JSAPI的时候,此项就变成必填项了
);
$config['sign'] = $this->getSignPay($config);
$xmlData = $this->ToXml($config);//转成xml数据
$postData = $this->http_post($xmlData);
$arrayData = $this->FromXml($postData);
if($arrayData['return_code'] == 'SUCCESS' $arrayData['result_code'] == 'SUCCESS'){
return $arrayData['prepay_id'];//重点来了:走了这么多路,就为了这个值。到这一步就证明成功一多半了。
}else{
return $arrayData;//返回错误
}
}
/**
* 获取签名
*/
public function getSignPay($config){
$key = 'xxxxxxx';//商户秘钥,就是自己生成的32位密码
$strA = 'appid='.$config['appid'].'&body='.$config['body'].'&mch_id='.$config['mch_id'].'&nonce_str='.$config['nonce_str'].'¬ify_url='.$config['notify_url'].'&spbill_create_ip'.$config['spbill_create_ip'].'&total_fee='.$config['total_fee'].'&trade_type='.$config['trade_type'];//ASCII 字典序
$strB = $strA.'&key='.$key;
$sign = strtoupper(md5($strB));//大写MD5
return $sign;
}
/**
* 随机字符串 32位
*/
public function getNonceStr($length = 32){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
/**
* array转XML
*/
public function ToXml($data){
if(!is_array($data) count($data) <= 0){
throw new WxPayException("数组数据异常!");
}
$xml = "<xml>";
foreach ($data as $key=>$val){
$xml.="<".$key.">".$val."</".$key.">";
}
$xml.="</xml>";
return $xml;
}
/**
* xml转array
*/
public function FromXml($xml){
if(!$xml){
throw new WxPayException("xml数据异常!");
}
libxml_disable_entity_loader(true);
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->values;
}
/**
* post 请求
*/
public function http_post($url,$param,$post_file=false){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) {
$is_curlFile = true;
} else {
$is_curlFile = false;
if (defined('CURLOPT_SAFE_UPLOAD')) {
curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false);
}
}
if (is_string($param)) {
$strPOST = $param;
}elseif($post_file) {
if($is_curlFile) {
foreach ($param as $key => $val) {
if (substr($val, 0, 1) == '@') {
}
}
}
$strPOST = $param;
} else {
$aPOST = array();
foreach($param as $key=>$val){
$aPOST[] = $key."=".urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST,true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}