<?php
/**
* PromptPay二维码内容字符串生成器
* 功能:生成符合EMVCo标准的PromptPay支付二维码内容字符串
* 输出:纯EMVCo格式数据字符串,可直接用于生成二维码
*/
/**
* 生成PromptPay二维码内容字符串
* @param array $params 包含生成参数的数组
* @return string|array 成功返回EMVCo格式字符串,失败返回错误数组
*/
function generatePromptPayQRString($params) {
// 验证必填参数
if (empty($params['maidata'])) {
return [
'result' => false,
'message' => '缺少必填参数: maidata'
];
}
/** EMVCo QR规范
** https://www.emvco.com/emv-technologies/qrcodes/
**/
// 有效载荷格式指示器
$payload = '00' . '02' . ($params['payload'] ?? '01');
// 商户账户信息
$mai = '29' . '37';
$mai .= '00' . '16' . ($params['mai'] ?? 'A000000677010111');
// 商户账户数据(手机号/PromptPay ID)
$maiData = $params['maidata'];
// 检测手机号/PromptPay ID格式
if (strlen($maiData) == 10) {
$appType = '01';
$appLen = 13;
$maiData = '66' . substr($maiData, 1);
} else {
$appType = '02';
$appLen = 13;
}
// 左侧补零
$appLen = str_pad($appLen, 2, 0, STR_PAD_LEFT);
$maiData = str_pad($maiData, $appLen, 0, STR_PAD_LEFT);
// 国家代码
$country = '58' . '02' . ($params['country'] ?? 'TH');
// 交易金额
$amount = ($params['amount'] ?? '0');
$amount = substr($amount, 0, 13);
$amountLen = str_pad(strlen($amount), 2, 0, STR_PAD_LEFT);
$amount = '54' . $amountLen . $amount;
// 支付类型(静态=11, 动态=12)
$payType = '01' . '02' . ($amount > 0 ? '12' : '11');
// 货币代码(ISO 4217)
$currency = '53' . '03' . ($params['currency'] ?? '764');
// 生成基础二维码数据
$data = $payload;
$data .= $payType;
$data .= $mai;
$data .= $appType . $appLen . $maiData;
$data .= $country;
if ($amount > 0) {
$data .= $amount;
}
$data .= $currency;
$data .= '63' . '04'; // CRC16字段
// 计算CRC16校验
$crc = strtoupper(substr(CRC16($data, 0xFFFF, 0x1021, true), -4));
// 完整二维码内容字符串(含CRC16)
$fullData = $data . $crc;
return [
'result' => true,
'data' => $fullData,
'message' => 'EMVCo格式二维码内容字符串生成成功'
];
}
/**
* CRC16校验计算函数
* @param string $input 输入数据
* @param int $init 初始值
* @param int $polynomial 多项式
* @param bool $hex 是否返回十六进制
* @return int|string 校验结果
*/
function CRC16($input, $init = 0xFFFF, $polynomial = 0x1021, $hex = false) {
$result = $init;
if (($length = strlen($input)) > 0) {
for ($offset = 0; $offset < $length; $offset++) {
$result ^= (ord($input[$offset]) << 8);
for ($bitwise = 0; $bitwise < 8; $bitwise++) {
if (($result <<= 1) & 0x10000) $result ^= $polynomial;
$result &= 0xFFFF;
}
}
}
if ($hex) {
return dechex($result);
}
return $result;
}
// 示例用法
$params = [
'maidata' => '123456', // 必选:商户账户数据(手机号或PromptPay ID)
'amount' => '1.12', // 可选:交易金额
'currency' => '764', // 可选:货币代码(THB)
];
$result = generatePromptPayQRString($params);
if ($result['result']) {
echo "EMVCo格式二维码内容字符串:\n";
echo $result['data'] . "\n\n";
echo "可用于生成二维码的完整链接:\n";
echo "https://chart.googleapis.com/chart?cht=qr&chs=256x256&chld=M|0&chl=" . urlencode($result['data']);
} else {
echo "生成失败:" . $result['message'];
}
php 生成泰国收款码
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 微信,支付宝,QQ三端个人支付二维码生成与监控!有PHP,JAVA接口回调,个人收款好助手! 实现收款即时到个人微...
- 前言 最近在逛博客时,发现很多博客都带了打赏功能,虽说打赏的人可能很少,但始终是一份心意,能让博主知道自己写的文章...
- 好多朋友有这样的收款需求,就是想要收款的时候带上备注并设置几个候选金额,但是这样的二维码之前的时候是需要在微信的支...
