1. 接口规则
星驿支付文档中心
  • AI快速对接
    • xypay-skills使用说明
  • 文档说明
    • 阅读对象
    • 版本说明
  • 术语
    • 支付模式
    • 名词解释
    • 支付产品
      • 付款码支付
      • 聚合码支付
      • PC支付
      • 小程序支付
        • 支付宝小程序支付
        • 微信小程序支付
      • APP支付
        • 微信支付
        • 支付宝支付
      • H5支付
        • 微信H5支付
        • 支付宝H5支付
        • 云闪付H5支付
        • 手机浏览器H5支付
      • Native支付
        • 支付宝支付
        • 云闪付支付
      • 终端支付
        • 智能云MIS
        • 智能APP
  • 接口规则
    • 协议规则
    • 常见问题
    • 安全规范
  • 支付交易
    • 交易前指引
      • 微信认证操作流程
      • 支付宝认证操作流程
      • H5页面微信支付对接前准备
      • H5页面支付宝支付对接前准备
      • 支付流程
      • 支付接入注意事项
      • 消费者IP获取指引
      • 微信小程序资金管控操作指南
    • 基础支付
      • 付款码支付
      • JSAPI支付
      • 订单查询
      • 扫码支付-星驿码
      • 扫码支付-官方码
      • 扫码支付-场景码
      • 关闭订单
      • 撤销订单
      • 退款
      • 退款查询
      • 授权码查询openid
      • 获取微信刷脸凭证
      • 获取银联用户标识
      • 风控ip检查
    • 半屏小程序支付
      • 使用说明
      • 小程序半屏-星驿付
      • 小程序半屏-场景
    • 扫码预授权
      • 扫码预授权
      • 预授权查询
      • 预授权撤销
      • 预授权撤销查询
      • 预授权完成
      • 预授权完成查询
      • 预授权完成撤销
      • 预授权完成撤销查询
    • 订单推送
      • 推送终端交易
      • 关闭推送终端交易
      • 碰一下推单状态查询
      • 碰一下订单取消
      • 碰一下订单推送
    • 智能终端SDK
      • 智能终端SDK
    • 交易通知及对账
      • 交易对账文件-场景应用
      • 交易对账文件-ISV
      • 交易和退款结果通知
      • 交易手续费通知
      • 后返对账文件-ISV
    • 刷卡预授权
      • 预授权完成撤销
      • 预授权撤销
    • 行业开票
      • 开票申请
      • 发票冲红
      • 发票结果查询
      • 发票结果通知
  • 商户管理
    • 进件前指引
      • 进件说明
      • 图片示例
      • 微信认证操作流程
      • 支付宝认证操作流程
      • 附件下载
    • 商户入网
      • 商户进件上传图片
      • 普通商户进件
      • 普通商户信息修改
      • 小微商户进件
      • 小微商户信息修改
      • 审核结果查询
      • 商户审核结果通知
      • 待审核商户撤回
      • 商户信息查询
      • 结算卡修改
      • 商户快捷修改
      • 受益人信息查询
      • 商户报备查询
      • 商户报备结果通知
      • 商户状态修改
      • 终端报备查询
      • 商户阶梯费率配置
      • 商户阶梯费率查询
    • 商户协议签约
      • 入网协议签约接口调用流程
      • 普通商户用户开户
      • 小微商户用户开户
      • 发短信验证码
      • 获取签约链接
      • 校验验证码
      • 校验验证码-补签
      • 签约结果通知
    • 微信支付宝认证
      • 微信申请单提交
      • 微信申请单撤销
      • 微信申请单状态查询
      • 微信商户授权状态查询
      • 支付宝申请单提交
      • 支付宝申请单撤销
      • 支付宝申请单状态查询
      • 支付宝商户授权状态查询
    • 商户开发配置
      • 绑定APPID配置
      • 微信支付目录配置
      • 微信公众号查询
      • 商户开发配置查询
      • 重发报备
      • 微信小程序冻结状态查询
      • 微信小程序冻结通知(非接口)
    • 商户限额调整
      • 商户限额查询
      • 商户提额申请
      • 商户提额记录查询
    • 商户风险处置
      • 商户风险处置通知
      • 风险商户图片上传
      • 微信官方风险商户文件
      • 支付宝官方风险商户文件
      • 风险商户异常流水查询
      • 风险商户调查列表
      • 风险商户调查详情
      • 风险调查单历史查询
      • 风险调查材料下载
      • 风险调查单处理
    • 商户手续费开票
      • 开具发票
      • 开票详情
      • 待开发票信息查询
      • 合并开票商户信息查询
      • 电子普票重发邮箱
      • 开票历史查询
    • 无界收款
      • 无界收款图片上传
      • 无界收款开通
      • 无界收款审核查询
      • 无界收款审核结果通知
  • 资金结算
    • D0开通及提现相关问题Q&A
    • D0结算业务
      • 产品介绍
      • 获取人脸识别链接
      • 人脸认证结果查询
      • D0开通
      • D0信息修改
      • D0状态查询
      • D0开通失败申诉
      • D0申诉结果查询
      • D0申诉结果通知
    • 特殊结算业务
      • 产品介绍
      • 结算业务申请
      • 结算业务变更
      • 结算业务结果查询
      • 结算业务结果通知
    • 提现查账
      • 手工提现
      • 到账记录查询
      • 到账记录批量查询
      • 秒到提现记录查询
      • 账户余额查询
      • 挂账记录查询
      • 补付申请
      • 提现结果通知
      • 账户余额变动通知
      • 提现对账文件
      • 批量结算提现通知
      • 到账附言配置
      • 查询到账附言
  • 星账云管家
    • 星账云管家
    • 功能开通
      • 功能开通(XZY001)
      • 编辑(XZY003)
      • 编辑上传付款凭证(XZY002)
      • 修改生效状态(XZY004)
      • 查询详情信息(XZY005)
      • 产品开通审核通知(XZY006)
    • 公共接口
      • 上传文件(XZY013)
    • 分账
      • 交易
        • 分账结算电子回单下载(XZY037)
        • 余额查询接口(XZY041)
        • 分账结果回调(XZY016)
        • 分账合并入账电子回单下载(XZY039)
        • 订单查询(XZY015)
        • 分账(XZY014)
        • 完结分账(XZY040)
        • 查询交易订单分账金额信息(XZY041)
        • 分账撤销退回(XZY017)
      • 客户管理
        • 新增客户(XZY018)
        • 分账授权申请接口-收单统一结算(XZY043)
        • 批量分账授权申请接口-收单统一结算(XZY044)
        • 合作状态调整(XZY020)
        • 解约/重启签约(XZY-001-002)
        • 编辑客户(XZY023)
        • 替换客户结算卡(XZY022)
        • 审核通知(XZY019)
        • 查询分账客户信息(XZY021)
    • 归集
      • 开户/授权
        • 归集授权申请接口-收单统一结算(XZY037)
        • 审核通知(XZY025)
        • 合作状态调整(XZY026)
        • 查询归集客户信息(XZY027)
        • 替换结算卡(XZY028)
        • 编辑信息(XZY029)
      • 交易
        • 归集合并入账电子回单下载(XZY040)
        • 归集结算电子回单下载(XZY038)
        • 余额查询接口(XZY042)
        • 订单查询(XZY031)
        • 归集(XZY030)
        • 归集结果回调(XZY032)
        • 归集撤销退回(XZY033)
    • 提现
      • 提现订单查询(XZY035)
      • 结算回调通知(XZY050)
      • 提现电子回单下载(XZY040)
      • 提现(XZY036)
    • 账户
      • 结算资金流水查询(XZY047)
      • 结算卡资金流水查询(XZY049)
  • 设备管理与推送
    • 设备管理
      • 收款设备绑定
      • 收款设备解绑
      • 收款设备绑定查询
      • 设备绑定/解绑结果通知
      • 音箱绑定
      • 音箱绑定查询
      • 音箱解绑
      • 设备信息修改
    • 设备推送
      • 音箱播报
      • 交易打印
  • 营销活动
    • 银行活动
      • 产品介绍
      • 图片上传
      • 商户补贴额度列表查询
      • 银行活动报名
      • 银行活动报名结果查询
      • 银行活动报名结果通知
      • 银行活动列表查询
      • 银行活动退出
    • 特殊行业活动
      • 产品介绍
      • 特殊行业活动报名申请
      • 特殊活动报名结果通知
      • 特殊行业商户活动查询
      • 特殊行业活动图片上传
    • 综合账户
      • 营销增资-订单
      • 营销增资-金额
      • 营销增资查询
      • 综合账户余额查询
      • 综合账户流水查询
      • 撤销营销增资-金额
    • 支付宝分期商家贴息
      • 贴息活动报名配置
      • 查询贴息活动
      • 修改活动里的费率
      • 贴息活动取消报名
      • 贴息活动商户列表查询
    • 增值服务
      • 获取增值营销产品列表
      • 获取增值营销产品明细
      • 获取分享链接
      • 推广结果列表查询
      • 推广结果详情
  • 慧徕店开放平台
    • 慧+SPI
      • 对接前准备
      • 商户同步
        • 开发配置
          • 请求域名
          • 加签&验签
        • 商户同步
        • 商户同步查询
        • 商户同步回调
      • 应用模块
        • 产品介绍
        • 开发配置
          • 请求域名
          • 加签&验签
        • 应用及增值服务列表查询
        • 商户应用注册及增值服务状态查询
        • 应用注册
        • 应用注册状态查询
        • 应用注册回调通知
        • 增值服务激活
        • 增值服务激活状态查询
        • 增值服务激活回调通知
      • 聚合支付SPI
        • 产品介绍
        • 开发配置
          • 签名方式
          • 公共参数
          • 验签方式
        • 支付API
        • 付款码支付
        • 扫码支付-官方码
        • JSAPI支付
        • 扫码支付-聚合码
        • 微信半屏小程序支付
        • 订单查询
        • 交易结果通知
        • 退款
        • 退款查询
        • 关闭订单
        • 获取银联用户标识
        • 公共参数
    • 应用开发API
      • 验签说明
      • 应用支付
      • 门店信息同步
      • 门店增值服务激活
  • 微信物业缴费
    • 小区楼房信息推送
    • 用户账单信息同步
    • 用户账单信息删除
    • 物业缴费订单查询
    • 代扣申请签约/解约通知
    • 代扣申请签约/解约结果同步
    • 微信代扣信息同步
    • 申请代扣扣费
  • 支付广告
    • SDK资源文件
    • 微信小程序广告
    • 支付宝小程序广告
    • 支付宝H5广告
  • 数据字典
    • MCC
      • 搜索查询二级mcc
      • 获取一级mcc目录
      • 获取二级mcc目录
    • 地区码
      • 获取省
      • 获取市
      • 获取区县
    • 落地银行
      • 落地银行查询
      • 落地银行下级机构查询
    • 银行信息
      • 获取银行省信息-联行号
      • 获取银行市信息-联行号
      • 银行信息查询
      • 查询联行号信息
      • 根据银行卡号获取银行信息
    • 连锁品牌
      • 获取连锁品牌信息
  • 分账服务
    • 订单分账
      • 订单分账
      • 订单分账结果查询
      • 订单分账撤销
      • 订单分账对帐文件
    • 余额分账
      • 余额分账
      • 余额分账结果查询
      • 可分账余额查询
    • 分账配置
      • 分账图片上传
      • 分账商户配置
      • 分账商户配置结果查询
      • 分账商户配置结果通知
      • 分账商户移除
      • 快捷创建资金接收方
      • 修改分账比例与金额
      • 商圈信息查询
  • 数据模型
    • PostPayRsp?
    • CompAccSubDocFileResponse
    • TermInfo
    • FileHeader
    • TitokDishItem
    • CompAccSubSumVo
    • CompAccSubDocRow
    • IsvRspListTermInfo
    • FileBody
    • TitokDataUploadReq
    • CompAccSubSumRow
    • GetTermInfoReq
    • StandardResponse
    • RunResultVo
    • ErrorResponse
  1. 接口规则

安全规范

1、域名与账号#

测试环境域名:https://xyf-server-test.postar.cn
uat环境域名:https://xyzscxm.postar.cn
生产环境域名:https://yyfsvxm.postar.cn
机构号,商户号对接时由国通对接人员提供。

2、测试注意(重要重要!!!必看!!!!!)#

注意:测试环境提供的银行间连生产测试账号是生产环境用来进行支付业务体验的账号,交易中产生的一切信息均为生产环境数据。用户支付需使用正式版微信、支付宝登陆用户的支付账号,使用用户的账号余额或绑定的银行卡等支付渠道进行支付。由于测试账号业务特点,不会产生清算资金划拨。所以使用测试账号时请务必使用小于0.1元的小金额,并请务必在支付当日完成退款。否则因隔日退款失败造成的测试资金损失由测试机构承担,并视为放弃资金。由于该账号为测试体验账号,所以禁止将该账号用于生产业务用途,禁止在商户真实业务中使用。对于将测试账号误用在商户真实业务造成的商户、用户等资金损失,由测试机构承担。 使用测试环境则视为同意上述使用协议。

3、压测说明#

生产环境、测试环境均严禁私自压测。如有压测需求,请先联系技术协调员,在【测试环境】进行!【生产环境】因风控及通道限制不提供压测支持!!
风控服务会自动关闭压测商户,因此请不要在生产环境进行压测。

4、签名算法#

说明:返回参数及请求参数说明:邮驿付&星驿付后期会对返回参数保留扩展的权力,扩展方式为新增参数但不会删除参数,请商户在解析邮驿付&星驿付返回参数时要支持邮驿付&星驿付可能扩展参数这种情况
1.
将所有传的参数(包括timeStamp和version,不含sign)拼接成一个字符串,拼接格式: key1=value1&key2=value2&key3=value3,其中 key1,key2,key3q,按字母ASCII值大小升序排序,区分大小写,比如reOrderNo是排在refundAmount的前面的。如果value是一个JSON,则将value转为json字符串再拼接,比如key1=value1&key2=value2&key3={"key4":"value4","key5":"value5"},key3中value的key可以不排序,但要保证顺序和传参时的顺序一致(若参数值为null,则不要拼接,如果是空字符串,则还是需要拼接)
2.
将上面拼接的字符串用sha256算法hash(注意:hash后的结果为小写字母,若是大写的,需转为小写),以交易查询接口为例,拼接后的字符串为:
String str = "agetId=xxx&custId=xxx&custLogin=xxx&orderNo=xxx&timeStamp=xxx&version=1.0.0",
之后用sha256算法:String sha256Str = SHA256.getSHA256(str);
3.
对上面hash后的字符串进行rsa签名操作,如:
String sign = encrypt(publicKey, sha256Str);
sign即为参数表中的sign参数,与其它参数一起构成最终的参数,其中: publicKey为公钥,对接时会提供。

5、签名demo#

1.
java
展开查看完整demo
2.
c#
展开查看完整demo
using Newtonsoft.Json;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using RestSharp;

namespace Api.XYFPay.Helper.Test
{
    public class RSA2Helper
    {
        private static string pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz5fdE4X6VCSD3cSmevVne5CCLnSm8tTXt4NwkV1BlG/JfFArV18DyF4xKiVc5Mbs/mflUiXh/CjbWv7F9/qQt17QQbWcoLZpu1yKJTNt5KBNNymv1SYeatXavbFKkpdn3NC+avf1CP1F6F0U3qBXtpVl+AE1ueR3wS3+CrSng5AQRcPmIhDT+jR9Q4NnbaJDQBZ3O+HMtynqbOfPFKF1k/hkPEiMhtDw5BEUyeOMYqXVpL4M9bttcmI8jg3NUddD2joSEwuofAxD4xMlfoY4cPTqdDYpdbWfy7V5CCQdMYgmJ13jZqg17TUTb/lLdK1ajWqEBW9GVCBkcx5Nx2SR8wIDAQAB";

        static void Main(string[] args)
        {
            try
            {
                var parameters = new Dictionary<string, object>
                {
                    ["agetId"] = "61000000340685",
                    ["custId"] = "60000001056272",
                    ["code"] = "282080689138406321",
                    ["orderNo"] = "25102309282349904699test7",
                    ["txamt"] = "1",
                    ["tradingIp"] = "220.249.188.179",
                    ["type"] = "A",
                    ["timeStamp"] = "20251023092824",
                    ["version"] = "1.0.0"
                };

                // 按键排序字典,包括下划线
                var sortedParameters = parameters.OrderBy(p => p.Key, StringComparer.Ordinal)
                 .Where(x=>x.Value!=null)
                 .Select(p => p.Value is string ? $"{p.Key}={p.Value}" : $"{p.Key}={JsonConvert.SerializeObject(p.Value)}");

                // 拼接排序后的参数
                var parameterString = string.Join("&", sortedParameters);
                Console.WriteLine("拼接的待签名串:" + parameterString);

                // 计算 SHA256 哈希
                string sha256Str = SHA256Encrypt(parameterString);
                Console.WriteLine("sha256:" + parameterString);
                string sign = EncryptByPublicKey(pubKey, sha256Str);
                parameters.Add("sign", sign);

                // 创建客户端
                var options = new RestClientOptions("https://xyf-server-test.postar.cn/yyfsevr/order/scanByMerchant");
                var client = new RestClient(options);
                var request = new RestRequest();
                request.Method = Method.Post;
                // 添加 Header
                request.AddHeader("Content-Type", "application/json");
                request.AddJsonBody(parameters);
                RestResponse response = client.Execute(request);
                Console.WriteLine("响应参数:" + response.Content);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"异常: {ex.Message}");
                Console.WriteLine(ex.StackTrace);
            }
        }

        public static string EncryptByPublicKey(string publicKey, string enptStr, string encoding = "UTF-8")
        {
            String pubKey = publicKey.Trim();
            String xmlPublicKey = RSAPublicKeyJava2DotNet(pubKey);

            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                byte[] cipherbytes;
                rsa.FromXmlString(xmlPublicKey);
                cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(enptStr), false);
                return Convert.ToBase64String(cipherbytes);
            }
        }

        /// <summary>
        /// 分段 RSA 公钥解密
        /// </summary>
        public static byte[] DecryptByPublicKey(string data, string publicKey)
        {
            byte[] encryptedData = Convert.FromBase64String(data);
            string xmlPublicKey = RSAPublicKeyJava2DotNet(publicKey);

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(xmlPublicKey);
                int keySizeBytes = rsa.KeySize / 8; // 2048 位 → 256 字节

                // 检查长度是否为 keySizeBytes 的整数倍
                if (encryptedData.Length % keySizeBytes != 0)
                    throw new Exception($"密文长度 {encryptedData.Length} 不是 {keySizeBytes} 的整数倍,可能密钥不匹配或数据损坏。");

                // 初始化 BouncyCastle 解密器
                var keyParam = DotNetUtilities.GetRsaPublicKey(rsa);
                IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
                cipher.Init(false, keyParam);

                using (var outStream = new MemoryStream())
                {
                    int offset = 0;
                    while (offset < encryptedData.Length)
                    {
                        byte[] block = new byte[keySizeBytes];
                        Array.Copy(encryptedData, offset, block, 0, keySizeBytes);
                        byte[] decryptedBlock = cipher.DoFinal(block);
                        outStream.Write(decryptedBlock, 0, decryptedBlock.Length);
                        offset += keySizeBytes;
                    }
                    return outStream.ToArray();
                }
            }
        }

        /// <summary>
        /// Java RSA 公钥格式转 .NET 格式
        /// </summary>
        private static string RSAPublicKeyJava2DotNet(string publicKey)
        {
            var publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
                Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
        }

        /// <summary>
        /// SHA256 哈希(返回小写十六进制)
        /// </summary>
        public static string SHA256Encrypt(string data)
        {
            using (var sha256 = SHA256.Create())
            {
                byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
                return BitConverter.ToString(hash).Replace("-", "").ToLower();
            }
        }
    }
}
3.
php
展开查看完整demo
<?php
namespace pay;

class Demo
{
    private string $apiUrl = "https://xyf-server-test.postar.cn/yyfsevr/order/scanByMerchant";

    private const PUBLIC_KEY_BASE64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz5fdE4X6VCSD3cSmevVne5CCLnSm8tTXt4NwkV1BlG/JfFArV18DyF4xKiVc5Mbs/mflUiXh/CjbWv7F9/qQt17QQbWcoLZpu1yKJTNt5KBNNymv1SYeatXavbFKkpdn3NC+avf1CP1F6F0U3qBXtpVl+AE1ueR3wS3+CrSng5AQRcPmIhDT+jR9Q4NnbaJDQBZ3O+HMtynqbOfPFKF1k/hkPEiMhtDw5BEUyeOMYqXVpL4M9bttcmI8jg3NUddD2joSEwuofAxD4xMlfoY4cPTqdDYpdbWfy7V5CCQdMYgmJ13jZqg17TUTb/lLdK1ajWqEBW9GVCBkcx5Nx2SR8wIDAQAB";

    private function getPublicKey(): string
    {
        return "-----BEGIN PUBLIC KEY-----\n"
            . chunk_split(self::PUBLIC_KEY_BASE64, 64, "\n")
            . "-----END PUBLIC KEY-----";
    }

    /**
     * 生成签名(SHA256摘要 + RSA公钥加密)
     */
    private function generateSign(array $params): string
    {
        ksort($params);
        $str = '';
        foreach ($params as $key => $value) {
            if ($value !== null && $value !== '') {
                $str .= ($str ? '&' : '') . $key . '=' . $value;
            }
        }
        $sha256 = hash('sha256', $str);
        $pubKey = openssl_pkey_get_public($this->getPublicKey());
        if ($pubKey === false) {
            throw new \RuntimeException('公钥加载失败:' . openssl_error_string());
        }
        $encrypted = '';
        if (!openssl_public_encrypt($sha256, $encrypted, $pubKey)) {
            throw new \RuntimeException('签名加密失败:' . openssl_error_string());
        }
        return base64_encode($encrypted);
    }

    /**
     * 通用请求方法:传入参数数组(不含sign),自动生成sign并POST JSON
     */
    public function request(array $params): array
    {
        $params['sign'] = $this->generateSign($params);

        $jsonData = json_encode($params);
        $ch = curl_init($this->apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($jsonData)
        ]);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 测试环境关闭SSL验证

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($curlError) {
            throw new \RuntimeException('cURL错误:' . $curlError);
        }
        if ($httpCode !== 200) {
            throw new \RuntimeException('HTTP错误:' . $httpCode . ', 响应:' . $response);
        }
        $result = json_decode($response, true);
        if ($result === null) {
            throw new \RuntimeException('JSON解析失败:' . $response);
        }
        return $result;
    }

    //公钥解密参考签名demo
    public function decode(string $signature): string
    {
        $binary = base64_decode($signature, true);
        if ($binary === false) {
            throw new \InvalidArgumentException('签名Base64解码失败');
        }
        $blockSize = 256;
        $chunks = str_split($binary, $blockSize);
        $pubKey = openssl_pkey_get_public($this->getPublicKey());
        if ($pubKey === false) {
            throw new \RuntimeException('公钥加载失败:' . openssl_error_string());
        }
        $decrypted = '';
        foreach ($chunks as $chunk) {
            $decryptedBlock = '';
            if (!openssl_public_decrypt($chunk, $decryptedBlock, $pubKey)) {
                throw new \RuntimeException('解密块失败:' . openssl_error_string());
            }
            $decrypted .= $decryptedBlock;
        }
        return $decrypted;
    }
}

// ========== 主函数演示 ==========
function main(): void
{
    echo "===== 支付接口请求演示 =====\n\n";

    try {
        $demo = new \pay\Demo();

        // 按您指定的参数构建请求体
        $params = [
            'agetId'    => '61000000340685',          // 机构号
            'custId'    => '60000001050305',          // 商户号
            'code'      => '283646680794562921',
            'orderNo'   => '202606220000000',
            'txamt'     => '1',
            'type'      => 'A',
            'tradingIp' => '220.249.188.179',
            'timeStamp' => time(),             // 当前时间戳(整数)
            'version'   => '1.0.0'
        ];

        echo "请求参数(不含sign):\n";
        print_r($params);
        echo "\n";

        echo "正在请求接口...\n";
        $result = $demo->request($params);
        echo "响应结果:\n";
        print_r($result);

    } catch (\Throwable $e) {
        echo "错误:" . $e->getMessage() . "\n";
        echo $e->getTraceAsString() . "\n";
    }

    echo "\n===== 程序结束 =====\n";
}

main();
?>
4.
python
展开查看完整demo
5.
go
展开查看完整demo
5.
nodejs
展开查看完整demo

6、sign验证失败排查方案#

检查下公钥是否正确,是否有把测试环境的公钥拿到生产环境来用;机构号和公钥一一对应,是否有把其他机构的公钥拿到当前机构来用,最好在实际加载公钥的位置打印下日志看看。
检查下参数字典序拼接的有没有问题,区分大小写,比如,reOrderNo是排在refundAmount的前面的;null的参数不要拼接,空字符串的参数需要拼接;值是对象的参数需要将对象转为json字符串后在拼接在key=后面。比如:
{
    "orderNo": "600889899046188256",
    "code": "134469628577908003",
    "latitude": "22.988558",
    "type": "P",
    "title": "授权码销售",
    "version": "1.0.0",
    "timeStamp": "20251119140829",
    "agetId": "61000000339134",
    "custId": "60000001038669",
    "tradingIp": "183.1.65.73",
    "detail": {
        "goods_detail": [
            {
                "goods_name": "星群50g口袋鸡胸肉奥尔良味",
                "quantity": 1,
                "price": 350,
                "goods_id": "6939733903026"
            }
        ]
    },
    "txamt": "350",
    "outTime": "15",
    "longitude": "113.269323",
    "subAppid": "",
    "remark": null
}
拼接后是如下字符串
agetId=61000000339134&code=134469628577908003&custId=60000001038669&detail={"goods_detail":[{"goods_name":"星群50g口袋鸡胸肉奥尔良味","quantity":1,"price":350,"goods_id":"6939733903026"}]}&latitude=22.988558&longitude=113.269323&orderNo=600889899046188256&outTime=15&subAppid=&timeStamp=20251119140829&title=授权码销售&tradingIp=183.1.65.73&txamt=350&type=P&version=1.0.0
注意上面detail,subAppid和remark3个特殊值的拼接规则。
修改于 2026-07-30 02:16:26
上一页
常见问题
下一页
微信认证操作流程
Built with