2017 © Pedro Peláez
 

library payments

payments,paypal,wechat,subscription

image

pheye/payments

payments,paypal,wechat,subscription

  • Wednesday, June 27, 2018
  • by pheye
  • Repository
  • 0 Watchers
  • 1 Stars
  • 322 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 1 Versions
  • 1510 % Grown

The README.md

payments

支付子系统:支持paypal rest, paypal ec, 微信支付,支付宝等支付方式;并支持账单,退款处理等功能., (*1)

TODO

  • 同步订阅状态

安装

需要注意,本包目前需要依赖于pheye/voyager,才能提供后台菜单,以及动态配置, (*2)

composer require pheye/payments dev-master

修改config/app.php, (*3)

'providers' => [
    // ...
    Pheye\Payments\PaymentServiceProvider::class,
],
'aliases' => [
    // ...
    'PaymentService' => Pheye\Payments\Facades\PaymentService::class,
]

配置

生成相关配置文件:, (*4)

$ php artisan vendor:publish --provider='Pheye\Payments\PaymentServiceProvider'
$ composer dump-autoload

完成数据库迁移:, (*5)

$ php artisan migrate

填充Voyager后台菜单:, (*6)

$ php artisan db:seed --class=PaymentVoyagerAdminSeeder

至此,基本配置就完成了。, (*7)

额外的配置

1.编辑app/User.php:, (*8)

<?php

namespace App;
use Pheye\Payments\Traits\Paymentable; 

class User extends Authenticatable           
{                                            
    use Paymentable;                                             
    // ...
} 

2.开放路由(这一步不推荐直接使用,仅做参考,建议根据实际需要添加对应路由),编辑routes/web.php:, (*9)

PaymentService::routes();

用法

后台

1.价格计划中至少要有一项,并且价格不为0。如下图:, (*10)

, (*11)

2.至少有一个有效的支付网关,默认名称为paypal ec,可通过.env中的CURRENT_GATEWAY修改使用的网关。如果没有可用账号测试,可直接使用我的配置。, (*12)

Gateway Name: paypal_ec
Factory Name: paypal_express_checkout
Config:
{"sandbox":true,"password":"GM8G8QUF96Z4SM5K","username":"95496875-facilitator_api1.qq.com","signature":"AFcWxV21C7fd0v3bYYYRCpSSRl31AXAjyVXCseIVl89pjDWPgVXyKvaa"}

买家测试账号:, (*13)

95496875-buyer2@qq.com
88888888

支付

注意必须使用WEB形式的路由才能被重定向到Paypal网站:, (*14)

POST /pay

参数:, (*15)

  • plan_name: plan的名称
  • gateway_name(可选): 如果指定就使用对应名称的网关,否则使用默认配置的网关
  • onetime(可选): 是否一次性支付,设置为1表示使用一次性支付,否则在支持循环扣款的网关下将默认使用循环扣款
  • amount(可选): 手动指定金额,只有plan的费用为0时,该参数将会有效
  • coupon(可选):优惠码

升级订阅

POST /pay

参数:, (*16)

  • plan_name: plan表示要升级的计划名称
  • gateway_name(可选): 如果指定就使用对应名称的网关,否则使用默认配置的网关
  • update: 表示升级计划

只能升不能降,升级过程补差价即可,同时不论是否升级成功,旧订阅都会被取消。差价计算公式:, (*17)

差价 = 新订阅价格 - 旧订阅最近的账单金额 * 剩余天数 / 30

请求退款

PUT /payments/{number}/refund_request

前端发起退款请求(如果env中存在ADMIN_EMAIL,并且是系统中的用户,则该用户会收到退款申请的通知邮件), (*18)

取消订阅

POST subscription/{id}/cancel

前端发起取消订阅, (*19)

票据下载

GET invoice/{invoice_id}

下载票据, (*20)

优惠券

GET /coupons?filter[code]={code}

获取代码为code的优惠券, (*21)

支付的网关类型

paypal_express_checkout Paypal EC
zhongwaibao 中外宝
alipay 支付宝
stripe Stripe

命令

payment:invoice 生成票据
payment:refund 退款
payment:sync-payments 同步订单
payment:cancel 取消订阅
payment:sync-plans 将本地计划同步到支付网关(对于Paypal REST和Stripe的循环扣款,这是必须的操作)

其他

事件

支付完成事件:Pheye\Payments\Events\PayedEvent, 在每次支付完成,会抛出此事件。$event->payment可取出对应的订单。, (*22)

取消完成事件:Pheye\Payments\Events\CancelledEvent,取消订阅完成,会抛出此事件。$event->subscription可取出对应的订阅, (*23)

退款完成事件:Pheye\Payments\Events\RefundedEvent,退款完成,会抛出此事件。$event->refund可取出退款申请单, (*24)

信用卡使用事件:Pheye\Payments\Events\CreditUsedEvent,用户使用信用卡支付时,会抛出此事件,这是保存信用卡信息的最佳时机,$event->credit取出信用卡信息,$event->client取出额外的用户相关信息。, (*25)

信用卡中的敏感信息,比如CVV,信用卡全卡号是获取不到的。, (*26)

为方便对事件的处理,包提供了默认的事件订阅器:Pheye\Payments\Listeners\PaymentEventSubscriber。, (*27)

当你需要处理事件时,可按如下方式修改:, (*28)

  1. 创建自己的App\Listeners\PaymentEventSubscriber:
<?php

namespace App\Listeners;

use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Pheye\Payments\Events\PayedEvent;
use Pheye\Payments\Events\RefundedEvent;
use Pheye\Payments\Events\CancelledEvent;
use Log;

class PaymentEventSubscriber extends \Pheye\Payments\Listeners\PaymentEventSubscriber
{

    /**
     * 处理支付完成事件
     */
    public function onPayed(PayedEvent $event)
    {
        $payment = $event->payment;
        Log::info('on payed test ' . $payment->number);
    }

    /**
     * 处理退款完成事件
     */
    public function onRefunded(RefundedEvent $event)
    {
        $refund = $event->refund;
        Log::info('on refuned test '.  $refund->payment->number);
    }

    /**
     * 处理取消订阅事件
     */
    public function onCancelled(CancelledEvent $event)
    {
        $sub = $event->subscription;
        Log::info('on cancellead test '.  $sub->agreement_id);
    }

    /**
     * 处理信用卡使用事件
     *
     * 这是保存信用卡信息的最佳时机
     */
    public function onCreditUsed(CreditUsedEvent $event)
    {
        // stub
        Log::info('credit used', ['credit' => $event->credit, 'client' => $event->client]);
    }
}
  1. 添加事件订阅器到app/Providers/EventServiceProvider.php:
    protected $subscribe = [
        // ...
        'App\Listeners\PaymentEventSubscriber',
    ];

异常处理

Pheye\Payments\Exceptions\BusinessErrorException (待补充), (*29)

注意点

  1. 当循环扣款,Plan中的amountsetup_fee都必须有值,前者控制每次循环扣款的费用,setup_fee则控制首次付款的费用;

TODO

  1. ADMIN_EMAIL的优化
  2. 考虑到setup_fee为0的情况,允许用户免费使用,过几天再扣款
  3. 循环扣款的订单同步文档说明

技术实现细节

Paypal EC的退款: https://developer.paypal.com/docs/classic/api/merchant/RefundTransaction_API_Operation_NVP/?mark=RefundTransaction, (*30)

Paypal EC的订单获取: https://developer.paypal.com/docs/classic/api/merchant/TransactionSearch_API_Operation_NVP/?mark=TransactionSearch, (*31)

The Versions