Полный анализ оплаты скан-кода WeChat

WeChat

Краткое введение в приложение, доступ, использование, подтверждение результатов платежа и другие сопутствующие процессы оплаты скан-кодом WeChat.

0 серия статей

первая серияПолный анализ платежей в приложении WeChat
вторая серияПолный анализ платежей в приложении Alipay
Серия третьяПолный анализ оплаты публичного аккаунта WeChat
Серия четвертаяПолный анализ оплаты скан-кода WeChat
Пятая серияПолный анализ Alipay мгновенный платеж
Серия шестьПолный анализ возврата средств WeChat
Седьмая серияПолный анализ возврата средств Alipay
Серия восьмаяОбновление платежной платформы Alipay и полный анализ обновлений

1 Применить

Шаги приложения для прямой ссылкиофициальная документация

Основные 2 куска:

  1. Подать заявку на открытие общедоступной платформы и создать приложение
  2. Подать заявку на оплату для активации торговой платформы

После одобрения всех заявок необходимые параметры для получения выплаты следующие:

1.1 AppID и AppSecret

Общедоступная платформа приложений для создания уникальной идентификации.
Войдите на общедоступную платформу WeChat и введите сведения о приложении, чтобы просмотреть AppID и AppSecret.

Paste_Image.png
Paste_Image.png

1.2 mch_id

После того, как платежное приложение WeChat будет завершено, торговая платформа WeChat отправит уведомление по электронной почте на ваш почтовый ящик, содержащее информацию о продавцах, открывших платеж.

Paste_Image.png
Paste_Image.png

1.3 API-ключ

То есть платежный ключ продавца, который в основном отвечает за обработку шифрования параметров связи. Войдите в торговую платформу WeChat (пароль учетной записи находится в электронном письме, отправленном торговой платформой WeChat)
Нажмите «Настройки учетной записи — Безопасность API» слева (при первом входе вы сможете установить сертификат операции, сначала установите сертификат операции). Нажмите «Установить ключ», чтобы установить собственный ключ.

Paste_Image.png
Paste_Image.png

1.4 Торговый сертификат

Он используется для некоторых интерфейсов, требующих проверки сертификата, таких как возврат средств. Нажмите «Центр учетных записей — Безопасность API» на платформе WeChat Merchant и нажмите «Загрузить сертификат».

Paste_Image.png
Paste_Image.png

После загрузки сертификата откройте сжатый пакет, и вы увидите сертификаты «apiclient_cert.pem», «apiclient_key.pem» и rootca.pem.

2 Процесс доступа

Ссылаться наДоступ к документации

Основные шаги:

  1. Единый заказ (размещается на сервере, требует параметров шифрования)
  2. Сгенерировать параметры платежа (на стороне сервера необходимо сгенерировать подпись)
  3. Создайте QR-код из платежного адреса для сканирования и оплаты напрямую
  4. Сервер получает результат платежа асинхронно

2.1 Единый порядок

$appid = "";  //你的appid
$mch_id = "";  //商户id
$wx_api_key = "";    //商户api秘钥
$out_trade_no = "";  //自己业务系统生成的交易no,可以唯一标识
$client_ip = "";  //客户端ip
$notify_url = "";    //接收支付结果通知url
$openid = "";    //微信授权获得的openid
$product_id = "";  //扫码的产品id 业务自定义的唯一物品标识

$UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";  //统一下单地址

$data = array();
$data['appid'] = $appid; 
$data['mch_id'] =$mch_id;
$data['nonce_str'] = randomStr(20);  //随机20位字符串
$data['product_id'] = $product_id;
$data['body'] = "微信扫码支付测试";
$data['detail'] = "微信扫码支付测试detail";
$data['out_trade_no'] = $out_trade_no;    
$data['total_fee'] = 1;  //注意 单位是分
$data['spbill_create_ip'] = $client_ip;
$data['openid'] = $openid;
$data['notify_url'] = $notify_url;
$data['trade_type'] = "NATIVE";  //交易类型
$data['sign'] =sign($data, $wx_api_key);    //签名

//转为xml格式
$xml_str = arrayToXmlStr($data); 

//发送请求 使用封装好的curl_post
$result = curl_post($UNIFIED_ORDER_URL, $xml_str);

//解析得到的值
$get_data = simplexml_load_string($raw_data, 'SimpleXMLElement', LIBXML_NOCDATA);
$get_para = array();
$get_sign = "";
foreach ($get_data->children() as $child) 
{    
  if($child->getName() == 'sign') {        
    $get_sign = strval($child);    
  } else {        
    $get_para[strval($child->getName())] = strval($child);    
   }
}

if($get_para['return_code'] !== "SUCCESS") {
    //return code fail
}

//验证签名
if(!verifySign($get_sign, $get_para, $wx_api_key)) {
    //验证签名非法
}

//获取支付地址
$code_url = $get_para['code_url'];

Некоторые функции:

/**
 * array转成xml str
 * @param $arr
 */
public static function arrayToXmlStr($arr) {    
  $xml_data = new \SimpleXMLElement("<xml></xml>");    
  Func::arrayToXml($arr, $xml_data);    
  return $xml_data->asXML();
}

/**
 * 生成指定长度的随机字符串(包含大写英文字母, 小写英文字母, 数字)
 * @param $length int 需要生成的字符串的长度
 * @return string 包含 大小写英文字母 和 数字 的随机字符串
 */
public static function randomStr($length){    
  //生成一个包含 大写英文字母, 小写英文字母, 数字 的数组    
  $arr = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));    
  $str = '';    
  $arr_len = count($arr);    
  for ($i = 0; $i < $length; $i++)    {        
    $rand = mt_rand(0, $arr_len-1);        
    $str.=$arr[$rand];    
  }    
  return $str;
}

/**
 * 微信签名
 * @param $para mixed 带签名参数数组
 * @param $wx_key string wxkey
 */
public static function sign($para, $wx_key) {    
  $unsign_str = Func::createLinkString(Func::argSort($para)) . "&key=" . $wx_key;    
  $sign = strtoupper(md5($unsign_str));    
  return $sign;
}

/**
 * 微信签名验证
 * @param $sign
 * @param $para
 * @param $wx_key
 * @return false-验证失败 true-验证成功
 */
public static function verifySign($sign, $para, $wx_key) {    
  $unsign_str = Func::createLinkString(Func::argSort($para)) . "&key=" . $wx_key;    
  $sign_str = strtoupper(md5($unsign_str));    
  if($sign === $sign_str) {        
    return true;    
  }    
  return false;
}

3. Оплата

Непосредственно преобразуйте code_url, полученный после размещения заказа, в QR-код для оплаты.Примечание: время действия QR-кода составляет 2 часа.

После завершения платежа, поскольку при сканировании кода не возвращается результат синхронизации, рекомендуется, чтобы бизнес-сторона опросила сервер, чтобы проверить статус транзакции.

4 Асинхронное уведомление о результате

Примечание. В частности, необходимо обратить внимание на правильную обработку повторных уведомлений после успешной проверки результата уведомления, а также на потерю средств, вызванную размещением нескольких отправлений.

$raw_data = $GLOBALS["HTTP_RAW_POST_DATA"];

$get_data = simplexml_load_string($raw_data, 'SimpleXMLElement', LIBXML_NOCDATA);
$get_para = array();
$get_sign = "";
foreach ($get_data->children() as $child) 
{    
  if($child->getName() == 'sign') {        
    $get_sign = strval($child);    
  } else {        
    $get_para[strval($child->getName())] = strval($child);    
   }
}

if($get_para['return_code'] !== "SUCCESS") {
    //return code fail
    die("<xml><return_code><![CDATA[FAIL]]></return_code></xml>");
}

//验证签名
if(!verifySign($get_sign, $get_para, $wx_api_key)) {
    //验证签名非法
    //todo
    die("<xml><return_code><![CDATA[FAIL]]></return_code></xml>");
}

//在这其实通知已经接受成功 可以返回成功告诉微信不用再次通知了
echo("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");

//业务状态码判断
if ($get_para['result_code'] !== 'SUCCESS') {       //状态码错误
  //支付错误 更改订单状态 记录log等 
  //...
}

//支付成功 更改订单状态 记录log等 
//todo

5 других

  1. После того, как клиент получит синхронный результат платежа, рекомендуется опросить сервер в течение определенного периода времени, чтобы получить результат сервера.Окончательный статус платежа зависит от сервера.

конец

Больше статей следите за моим публичным аккаунтом

我的公众号
мой публичный аккаунт