微信App支付
前言
本篇文章将结合自己实际开发经验,从一下几个方面介绍微信app支付,什么是微信app支付?支付流程是什么样的? 前期需要准备些什么?结合官方文档和实际代码带大家走流程.
正文
微信app支付是什么(哪种情况下需要用到)?
微信app支付,顾名思义指的是需要在app内使用,需要安卓或者ios配合发起支付.
微信app支付流程(支付的通用流程)?
微信官方支付流程
这个流程图整的有点丑,大家凑合看,第一次用,尴尬脸
微信app支付需要准备什么?
开放平台+移动应用(申请了支付功能的移动应用)+该应用对应的商户平台
商户平台里面设置秘钥(随机的32位字符串apikey)
支付(结合微信官方提供的文档和服务端的实际代码)
预支付订单请求地址 https://api.mch.weixin.qq.com/pay/unifiedorder
下面代码为服务端发起请求微信生成预订单,及处理返回数据给客户端发起支付的过程代码,(看10遍不如结合自己的项目写一遍)
<?php
class Payment
{
private static $config = array();
public function __construct()
{
self::$config = array(
'appId' =>'xxxxxxxx',
'mch_id' =>'xxxx',
'notify_url' => 'http://www.xxx.com/xxx',
'apiKey' => 'xxxxxxxxxxxxxxx',
'URL' => 'https://api.mch.weixin.qq.com/pay/unifiedorder'
);
}
public function appPay($uid,$rmb)
{
// 1. 创建系统订单,这里就不去操作了,生成系统内部未支付订单,结合自己的逻辑去做.
$orderNo = $uid.time();
// 2. 初始化请求数据.微信单位为分.
$xmlDate = $this->initOrderData($rmb*100,$orderNo);
// 3. 请求微信服务生成预支付订单凭证.
$xmlResponse = $this->postXml($xmlDate);
// 4. xml数据转为数组
$response = $this->xmlToArray($xmlResponse);
// 如果失败.
if (strcmp($response['RETURN_CODE'], 'FAIL') === 0) {
$message = $response['RETURN_MSG'];
$code = "1";
$data = "";
}
//如果成功,返回客户端所需要的数据.
$data = $this->initAppData($response);
$message = "success";
$code = "0";
$data = array();
return json_encode(array("message" => $message,'code' => $code,'data' => $data));
}
protected function initOrderData($rmb,$orderNo)
{
$params = array(
'appid' => self::$config["appId"],// 开放平台下,该app应用的appid.
'mch_id'=> self::$config["mch_id"],// 该开放平台应用对应的商户平台内的商户号.
'nonce_str' => md5("test".time()),// 随机字符串.
'body' => '测试',
'out_trade_no' => $orderNo,
'fee_type' => 'CNY', //货币类型
'total_fee' => $rmb,// 支付金额,单位为分
'spbill_create_ip' => "192.168.1.103",
'time_start' =>date("YmdHis"),
'time_expire'=> date("YmdHis",strtotime("+2hours")),
'notify_url' => self::$config["notify_url"],// 支付异步回调地址,
'trade_type' => 'APP',
);
// 参数排序按照键的ascii码值升序排列.
ksort($params);
// 将参数转化成url键值对的形式.
$str = $this->arrayToKeyValue($params);
// 拼接商户秘钥apiKey
$str .= "key=".self::$config["apiKey"];
// 拼接加密参数.
$params["sign"] = strtoupper(md5($str));
// 将数组转为xml格式
$xmlDate = $this->arrayToXml($params);
return $xmlDate;
}
/**
* 将数组转化成url键值对格式.
*
* @param array $param
*
* @return string
*/
protected function arrayToKeyValue($param)
{
$str = '';
foreach ($param as $k => $v) {
$str.= $k."=".$v."&";
}
return $str;
}
/**
* 将数组转为xml格式的数据.
*
* @param array $param
*
* @return string
*/
protected function arrayToXml($param)
{
$xml = "<xml>";
foreach ($param as $key => $value) {
$xml .= "<$key>{$value}<$key>";
}
$xml .= "</xml>";
return $xml;
}
/**
* xml格式数据转换成array.
*
* @param $xml
*
* @return array
*/
protected function xmlToArray($xml)
{
$parser = xml_parser_create();
xml_parse_into_struct($parser, $xml, $data, $index);
$arr = array();
foreach ($data as $key => $value) {
$arr[$value['tag']] = $value['value'];
}
return $arr;
}
/**
* 提供客户端发起微信支付所需要的数据.
*
* @param $data
*
* @return array
*/
protected function initAppData($data)
{
$appData = array(
'appid' => $data['APPID'],
'partnerid' => $data['MCH_ID'],
'prepayid' => $data['PREPAY_ID'],
'package' => 'Sign=WXPay',
'noncestr' => time().rand(1000,999),
'timestamp' => time()."",
);
ksort($appData);
$str = $this->arrayToKeyValue($appData);
//拼接商户秘钥apiKey
$str .= "key=".self::$config["apiKey"];
//拼接加密参数.
$appData["sign"] = strtoupper(md5($str));
return $appData;
}
/**
* post请求微信服务.
* @param $xml
* @param int $second
* @return mixed|string
*/
protected function postXml($xml, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, static::$config["URL"]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);//严格校验
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
curl_close($ch);
//返回结果
if ($data) {
return $data;
} else {
return "<xml><return_code>FAIL</return_code><return_msg>系统繁忙!请稍后再试.</return_msg></xml>";
}
}
}
正确返回格式参考
客户端ios或者安卓拿到对应的数据就可以发起微信支付啦!
"data": {
"appid": "wx6d98ecxxxxxe63a",
"noncestr": "47b37529df3d9ae3c1fb39a4fafdc63d",
"package": "Sign=WXPay",
"partnerid": "1294xxxxx1",
"prepayid": "wx201xxxxxxxxxxxxxxxxxxxx",
"timestamp": "1500569824",
"sign": "9B7364700B450850A505xxxxxxxxxxxx"
}
关于回调那块就不讲啦,大家可以看下官方文档
谢谢大家的支持,加个关注呗,如果可以,后期会陆续和大家分享支付宝支付,公众号支付,微信网页登录及其他自己在项目中收获的经验等
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。