添加URL
分享
Payment解决什么问题

Payment 的目的是简化大家在对接主流第三方时需要频繁去阅读第三方文档,还经常遇到各种问题。 Payment 将所有第三方的接口进行了合理的建模分类,对大家提供统一的接入入口,大家只需要关注自身业务并且支付系统设计上。

目前已经集成:支付宝、微信、招商绝大部分功能。也欢迎各位贡献代码。 贡献指南

当前 Payment 项目仅支持 PHP version > 7.0 的版本,并且仅支持通过 composer 进行安装。

需要 PHP 安装以下扩展:

- ext-curl
- ext-mbstring
- ext-bcmath
- package-Guzzle

composer安装方式:

直接在命令行下安装:

composer require "riverslei/payment:*"

通过项目配置文件方式安装:

"require": {
    "riverslei/payment": "*"

按照上面的步骤完成安装后,即可在项目中使用。

对于整个过程,提供了唯一的入口类 \Payment\Client,每一个渠道,均只介绍 APP支付异步/同步通知 该如何接入。会重点说明每个请求支持的参数。

APP支付demo

$config = [
    // 配置信息,各个渠道的配置模板见对应子目录
// 请求参数,完整参数见具体表格
$payData = [
    'body'         => 'test body',
    'subject'      => 'test subject',
    'trade_no'     => 'trade no',// 自己实现生成
    'time_expire'  => time() + 600, // 表示必须 600s 内付款
    'amount'       => '5.52', // 微信沙箱模式,需要金额固定为3.01
    'return_param' => '123',
    'client_ip'    => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1', // 客户地址
];``
// 使用
try {
    $client = new \Payment\Client(\Payment\Client::WECHAT, $wxConfig);
    $res    = $client->pay(\Payment\Client::WX_CHANNEL_APP, $payData);
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
    exit;
} catch (\Payment\Exceptions\GatewayException $e) {
    echo $e->getMessage();
    var_dump($e->getRaw());
    exit;
} catch (\Payment\Exceptions\ClassNotFoundException $e) {
    echo $e->getMessage();
    exit;
} catch (Exception $e) {
    echo $e->getMessage();
    exit;

异步/同步通知

// 自己实现一个类,继承该接口
class TestNotify implements \Payment\Contracts\IPayNotify
     * 处理自己的业务逻辑,如更新交易状态、保存通知数据等等
     * @param string $channel 通知的渠道,如:支付宝、微信、招商
     * @param string $notifyType 通知的类型,如:支付、退款
     * @param string $notifyWay 通知的方式,如:异步 async,同步 sync
     * @param array $notifyData 通知的数据
     * @return bool
    public function handle(
        string $channel,
        string $notifyType,
        string $notifyWay,
        array $notifyData
        //var_dump($channel, $notifyType, $notifyWay, $notifyData);exit;
        return true;
$config = [
    // 配置信息,各个渠道的配置模板见对应子目录
// 实例化继承了接口的类
$callback = new TestNotify();
try {
    $client = new \Payment\Client(\Payment\Client::ALIPAY, $config);
    $xml = $client->notify($callback);
} catch (InvalidArgumentException $e) {
    echo $e->getMessage();
    exit;
} catch (\Payment\Exceptions\GatewayException $e) {
    echo $e->getMessage();
    exit;
} catch (\Payment\Exceptions\ClassNotFoundException $e) {
    echo $e->getMessage();
    exit;
} catch (Exception $e) {
     echo $e->getMessage();
     exit;

从上面的例子简单总结下,所有的支持的能力,通过 \Payment\Client 对外暴露方法;所有需要的常量也在这个类中进行了定义。其次需要一个 $config,关于config的模板,在每个渠道下面去看。最后一个传入请求的参数,完整的参数会在每个渠道中列出来,需要说明的是这些参数名字根据第三方文档部分进行了改写。在使用的时候请注意。

参数选项说明:

  • Y: 必须
  • N: 非必须
  • 配置文件模板

    $config = [
        'use_sandbox' => true, // 是否使用沙盒模式
        'app_id'    => '2016073100130857',
        'sign_type' => 'RSA2', // RSA  RSA2
        // 支付宝公钥字符串
        'ali_public_key' => '',
        // 自己生成的密钥字符串
        'rsa_private_key' => '',
        'limit_pay' => [
            //'balance',// 余额
            //'moneyFund',// 余额宝
            //'debitCardExpress',// 	借记卡快捷
            //'creditCard',//信用卡
            //'creditCardExpress',// 信用卡快捷
            //'creditCardCartoon',//信用卡卡通
            //'credit_group',// 信用支付类型(包含信用卡卡通、信用卡快捷、花呗、花呗分期)
        ], // 用户不可用指定渠道支付当有多个渠道时用“,”分隔
        // 与业务相关参数
        'notify_url' => 'https://dayutalk.cn/notify/ali',
        'return_url' => 'https://dayutalk.cn',
    APP支付请求参数
    

    对应channel: \Payment\Client::ALI_CHANNEL_APP

    transaction_id 该交易在支付宝系统中的交易流水号。最短 16 位,最长 64 位。和transaction_id不能同时为空,如果同时传了 transaction_id和 trade_no,则以 transaction_id为准 operator_id 卖家端自定义的的操作员 ID transaction_id 该交易在支付宝系统中的交易流水号。最短 16 位,最长 64 位。和transaction_id不能同时为空,如果同时传了 transaction_id和 trade_no,则以 transaction_id为准 'app_id' => 'wxxxxxxxx', // 公众账号ID 'sub_appid' => 'wxxxxxxxx', // 公众子商户账号ID 'mch_id' => '123123123', // 商户id 'sub_mch_id' => '123123123', // 子商户id 'md5_key' => '23423423dsaddasdas', // md5 秘钥 'app_cert_pem' => 'apiclient_cert.pem', 'app_key_pem' => 'apiclient_key.pem', 'sign_type' => 'MD5', // MD5 HMAC-SHA256 'limit_pay' => [ //'no_credit', ], // 指定不能使用信用卡支付 不传入,则均可使用 'fee_type' => 'CNY', // 货币类型 当前仅支持该字段 'notify_url' => 'https://dayutalk.cn/v1/notify/wx', 'redirect_url' => 'https://dayutalk.cn/', // 如果是h5支付,可以设置该值,返回到指定页面
    支付请求参数

    对应channel: \Payment\Client::WX_CHANNEL_APP、WX_CHANNEL_BAR、WX_CHANNEL_LITE、WX_CHANNEL_PUB、WX_CHANNEL_QR、WX_CHANNEL_WAP

    bill_type ALL(默认值),返回当日所有订单信息(不含充值退款订单)SUCCESS,返回当日成功支付的订单(不含充值退款订单)REFUND,返回当日退款订单(不含充值退款订单) RECHARGE_REFUND,返回当日充值退款订单 trade_no 商户系统内部订单号,要求32个字符内,且在同一个商户号下唯一。transaction_id、trade_no二选一,如果同时存在优先级:transaction_id> trade_no refund_no 商户系统内部的退款单号,商户系统内部唯一 ,同一退款单号多次请求只退一笔。 total_fee 订单总金额,单位为元 refund_fee 退款总金额,订单总金额,单位为元 refund_desc 若商户传入,会在下发给用户的退款消息中体现退款原因 refund_account 仅针对老资金流商户使用 'branch_no' => 'xxx', // 商户分行号,4位数字 'mch_id' => 'xxxx', // 商户号,6位数字 'mer_key' => 'xxxxxx', // 秘钥16位,包含大小写字母 数字 // 招商的公钥,建议每天凌晨2:15发起查询招行公钥请求更新公钥。 'cmb_pub_key' => 'xxxxx', 'op_pwd' => 'xxxxx', // 操作员登录密码。 'sign_type' => 'SHA-256', // 签名算法,固定为“SHA-256” 'limit_pay' => 'A', // 允许支付的卡类型,默认对支付卡种不做限制,储蓄卡和信用卡均可支付 A:储蓄卡支付,即禁止信用卡支付 'notify_url' => 'https://dayutalk.cn/notify/cmb', // 支付成功的回调 'sign_notify_url' => 'https://dayutalk.cn/notify/cmb', // 成功签约结果通知地址 'sign_return_url' => 'https://dayutalk.cn', // 成功签约结果通知地址 'return_url' => 'https://dayutalk.cn', // 如果是h5支付,可以设置该值,返回到指定页面
    支付请求参数 设计支付系统

    Payment 解决了对接第三方渠道的各种问题,但是一个合理的支付完整系统该如何设计?估计大家还有很多疑问。关于支付系统的设计大家可以参考该项目:https://github.com/skr-shop/manuals

    这是我与小伙伴开源的另外一个关于电商的项目,里边对电商的各个模块设计进行了详细的描述。

    支持的接口

    对应到第三方的具体接口

  • APP支付
  • 电脑网站支付
  • 撤销交易 条码/扫码支付会用到
  • 下载对账单
  • 转账到支付宝
  • 支付宝转账查询
  • 交易创建 条码/扫码支付会用到

    支持 普通商户与服务商两个版本

  • 付款码支付
  • JSAPI支付
  • Native支付
  • APP支付
  • 小程序支付
  • 下载对账单
  • 下载资金账单
  • 转账到银行卡 该接口还有些问题待处理
  • 转账到微信零钱
  • 银行转账查询
  • 微信转账查询
  • APP支付
  • PC扫码支付
  • 二维码支付
  • 查询入账明细
  • 下载退款对账单
  • 下载已结账单for商户
  • 下载已结账单for银行
  • 下载对账单
  • 查询招行公钥
  • 整个代码结构的设计,待补充

    接入一个新的能力该如何操作,待补充

    第三方文档 License

    The code for Payment is distributed under the terms of the MIT license (see LICENSE).