join / php-payment
php
v0.2.7
2022-02-22 02:52 UTC
Requires
- php: >=7.2.0
- alipaysdk/easysdk: ^2.2
- overtrue/wechat: ~4.0
- topthink/framework: 5.1.*
Requires (Dev)
README
github (最新代码) https://github.com/SantiagoFan/php-payment
gitee (定期同步) https://gitee.com/san_fan/php-paymentgit
整体框架
composer 安装
需要 composer 版本2+
composer require join/php-payment
包地址 https://packagist.org/packages/join/php-payment
require 依赖
php:>=7.2.0
代码结构
如何参与开发成为代码贡献人员
- 将项目fork到自己帐号
- 修改代码完成测试
- 提交commit push 到自己的仓库
- New pull request(简称pr) 合并请求到主库等待合并
使用教程
1.安装包 composer 包
composer require join/php-payment
2.创建数据表
复制源码文件夹的sql 脚本创建 交易流水表(此表作为所有支付进出的流水信息记录),具体业务订单信息请自己单独创建,参照下面的myorder
vendor/join/php-payment/doc/model.sql
字段 | 数据类型 | 可空 | 含义 |
---|---|---|---|
id | varchar(64) | not null | 支付记录表 |
title | varchar(128) | null | 支付项目名称 如:商品-橘子5斤 |
is_refund | tinyint(1) | null | 是否为退款 |
state int | default 0 | null | 支付完成状态 -1撤销 0 默认 1 交易中 2支付完成 |
business_name | varchar(50) | null | 业务类别:1.商品支付 |
business_no | varchar(128) | null | 内部业务 关联订单号码 |
pay_channel | varchar(50) | null | 支付渠道:alipay,wxpay |
pay_channel_no | varchar(128) | null | 支付渠道 返回的外部订单号 |
amount | decimal(10,2) | null | 操作金额 支付为正 退款为负 |
real_amount | decimal(10,2) | null | |
apply_time | datetime | null | 下单时间 |
complete_time | datetime | null | 交易完成时间 |
original_amount | decimal(10,2) | null | 原订单交易金额 |
original_id | varchar(64) | null | 原始交易订单 |
3.编写配置类(实现 IPaymentConfig 接口)
- getPayConfig 是获取微信支付宝支付通道所需参数的方法
- getBusinessMap 是通过业务名称获取 业务类(具体指业务系统里需要有支付需求的订单如,商户购买订单、充值订单等)
- getPayChannel 是前端业务场景对应支付通道的配置
class PaymentConfig implements IPaymentConfig{ // 注入配置 public static function init(){ $config = new self(); PayFactory::init($config); } /** * 注入配置信息 * @param string $type * @return mixed */ public function getPayConfig(string $type){ // 方式一:代码里直接编写参数 // $config = [ // "wxpay"=>[], // "alipay"=>[] // ]; // 方式二:单独配置文件 config/payment.php $config = Config::get('payment.'); return $config[$type]; } /** * 获取业务类映射关系 * @return array|mixed */ public function getBusinessMap(){ // 具体请映射业务类 return [ "recharge_order"=>Model_MemberBalance::class, ]; } /** * 配置客户端 对应支付通道 * @param string $client * @return string */ public function getPayChannel(string $client): string { // 客戶端支付方式映射支付渠道 $channel=[ PayClient::WEIXIN_MP => PayChannel::WEIXIN_PAY_JS, PayClient::WEIXIN_QRCODE => PayChannel::WEIXIN_PAY_NATIVE, PayClient::ALI_MP => PayChannel::ALI_PAY_JS, PayClient::ALI_PAY_QRCODE => PayChannel::ALI_PAY_NATIVE, ]; return $channel[$client]; } }
配置示例 config/payment.php
<?php
use think\facade\Config;
use think\facade\Env;
return [
// +----------------------------------------------------------------------
// | 微信 支付参数
// +----------------------------------------------------------------------
"wxpay"=>[
'app_id' => '',
'mch_id' => '',
'key' => '',
'pay_notify_url' =>'https://' . Config::get('app_host') . '/payment/notify/wxpay',
'refund_notify_url' =>'https://' . Config::get('app_host') . '/payment/notify/wxrefund',
'cert_path' =>Env::get('root_path'). 'cert/apiclient_cert.pem',
'key_path' =>Env::get('root_path'). 'cert/apiclient_key.pem'
],
// +----------------------------------------------------------------------
// | 支付宝 支付参数
// +----------------------------------------------------------------------
"alipay"=>[
'app_id' => '',
'merchantPrivateKey' => '',
'alipayPublicKey'=>'',
'encryptKey'=>'',
'pay_notify_url' => 'https://' . Config::get('app_host') . '/payment/notify/alipay'
]
];
支付前注入配置
PaymentConfig::init();
4.集成异步通知 Controller
此通知入口对应地址需要和配置类的通知地址一致
class NotifyController extends BaseNotifyController { public function __construct(App $app = null) { parent::__construct($app); PaymentConfig::init(); //如果全局钩子函数注入配置则不用写次函数 } }
如果需要全局处理 支付成功后或者退款后的业务,notify 类覆盖父类方法PaySuccess
或者 RefundSuccess。
如果需要处理业务订单成功后的业务,请在相关业务model 里的PaySuccess方法处理
5.编写业务类 Model
- .编写自己的业务类MyOrder(可以实现多个不同业务类,如商城订单、充值订单,MyOrder只是示例名字,具体的写自己的名字!!!!) 。
- .每个业务需要实现 IPayableOrder 或者直接继承 BasePayableOrder 基类省时省力
- .BasePayableOrder 集成了 Thinkphp 的Model 类,可直接集成Model的数据库操作函数
class MyOrder extends BasePayableOrder { // 业务名称 protected $pk ='order_no'; /** * 因为字段不一样 覆盖父级方法 * 如果业务类包含:title、amount、order_no 则无需编写次方法 * @return Model_PayOrder */ // public function CreatePayOrder():Model_PayOrder // { // $pay_order = new Model_PayOrder(); // $pay_order['title']= $this['name']; // 支付标题 // $pay_order['amount']= $this['price']; // 支付金额 // $pay_order['business_no']= $this['order_no']; // 订单号 // return $pay_order; // } public function PaySuccess(Model_PayOrder $pay_order) { // 支付成功后 业务单 后续逻辑 } public function RefundedSuccess(Model_PayOrder $pay_refund_order) { // 退款成功后 业务单 后续逻辑 } }
6.编写业务调用支付
// 注入配置参数(全局注入则不用写这个) PaymentConfig::init(); // 方式1:创建自己的业务订单 // $bus_order = new MyOrder(); // $bus_order['name'] ='用户充值'; // $bus_order['price'] = 11.00; // 方式2: 从数据库查询 后支付 $bus_order = MyOrder::get('10001'); //支付客户端类型(就是你想调用哪种支付方式) $client = PayClient::WEIXIN_QRCODE; //小程序参数 $params = []; // 获得支付参数 $res = $bus_order->PayOrder($client, $params);
支付传入参数 $params
微信js 支付需要传入openid
$params = ['openid'=>$openid];
支付宝js 支付需要传入buyer_id
$params = ['buyer_id'=>$buyer_id];