php 生成泰国收款码

<?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'];
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容