perafan/cashier-openpay

Laravel Cashier 提供了访问 Openpay 订阅计费服务的表达式丰富、流畅的接口。

2.0.0 2020-10-17 07:47 UTC

This package is auto-updated.

Last update: 2024-09-29 05:47:58 UTC


README

Latest Version on Packagist Total Downloads Build Status StyleCI

Banner

安装

使用 Composer 安装 Openpay Cashier 包

composer require perafan/cashier-openpay

运行以发布迁移、WebHookController 和配置文件。

php artisan vendor:publish --tag="cashier-openpay-migrations"
php artisan vendor:publish --tag="cashier-openpay-configs"
php artisan vendor:publish --tag="cashier-openpay-webhook-controller"

Cashier 服务提供者注册了自己的数据库迁移目录,因此请记住在安装包后迁移数据库。Cashier 迁移将在您的用户表中添加几个列,并创建一个新的订阅表以存储所有客户的订阅

php artisan migrate

配置

可计费模型

Billable 特性添加到您的模型定义中。 Billable 特性提供了执行常见计费任务的方法(创建订阅、添加支付方式信息、创建费用等)

use Perafan\CashierOpenpay\Billable;

class User extends Authenticatable
{
    use Billable;
}

Cashier 假设您的 Billable 模型将是 Laravel 附带的 App\Models\User 类。如果您希望更改此设置,您可以在您的 `.env` 文件中指定不同的模型

OPENPAY_MODEL=App\Models\User

API 密钥

接下来,您应该在您的 `.env` 文件中配置您的 Openpay 密钥。您可以从 Openpay 控制面板检索您的 Openpay API 密钥。

OPENPAY_PUBLIC_KEY=-your-openpay-public-key-
OPENPAY_PRIVATE_KEY=-your-openpay-private-key-
OPENPAY_ID=-your-openpay-id-

环境

为了方便和安全,客户端库默认启用沙盒模式。这允许在实施 Openpay 时测试自己的代码,在生产环境中在扣款任何信用卡之前。

OPENPAY_PRODUCTION_MODE=false

日志记录

Cashier 允许您指定用于记录所有 Openpay 相关异常的日志通道。

OPENPAY_LOG_ERRORS=true

显示 openpay 错误(可选)

如果您想捕获所有 openpay 异常,请添加到您的 app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

use Perafan\CashierOpenpay\OpenpayExceptionsHandler;
...

class Handler extends ExceptionHandler
{
    use OpenpayExceptionsHandler;

    ...

    public function render($request, Throwable $exception)
    {
        if ($this->isOpenpayException($exception)) {
            return $this->renderOpenpayException($request, $exception);
        }
        return parent::render($request, $exception);
    }
}

要在 blade 中渲染错误响应,您可以使用以下片段。

使用 bootstrap 显示错误

@if($errors->cashier->isNotEmpty())
    <div class="alert alert-danger" role="alert">
        @foreach ($errors->cashier->keys() as $key)
            <strong>{{ $key }} :</strong> {{ $errors->cashier->get($key)[0] }} <br>
        @endforeach
    </div>
@endif

使用 tailwindcss 显示错误

@if($errors->cashier->isNotEmpty())
    <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
        @foreach ($errors->cashier->keys() as $key)
            <strong class="font-bold">{{ $key }} :</strong> {{ $errors->cashier->get($key)[0] }} <br>
        @endforeach
    </div>
@endif

您自己的 Openpay 异常处理器(可选)

您可以通过创建自己的处理器来修改响应。

trait MyOpenpayExceptionsHandler
{
    use OpenpayExceptionsHandler {
        OpenpayExceptionsHandler::renderOpenpayException as parentRenderOpenpayException;
    }
    
    public function renderOpenpayException(Request $request, OpenpayApiError $exception)
    {
        $this->parentRenderOpenpayException($request, $exception);
        
        //your code
    }
} 

用法

客户

在用户上

向商家添加新客户

$user->createAsOpenpayCustomer();

//Or you can send additional data

$data = [
    'name' => 'Teofilo',
    'last_name' => 'Velazco',
    'phone_number' => '4421112233',
    'address' => [
        'line1' => 'Privada Rio No. 12',
        'line2' => 'Co. El Tintero',
        'line3' => '',
        'postal_code' => '76920',
        'state' => 'Querétaro',
        'city' => 'Querétaro.',
        'country_code' => 'MX'
    ]
];

$openpay_customer = $user->createAsOpenpayCustomer($data);

获取客户

$openpay_customer = $user->asOpenpayCustomer();

更新客户

$openpay_customer  = $user->asOpenpayCustomer();
$openpay_customer->name = 'Juan';
$openpay_customer->last_name = 'Godinez';
$openpay_customer->save();

删除客户

$openpay_customer = $user->asOpenpayCustomer();
$openpay_customer->delete();

在商家上

向商家添加新客户

use Perafan\CashierOpenpay\Openpay\Customer as OpenpayCustomer;

OpenpayCustomer::create([
    'name' => 'Teofilo',
    'last_name' => 'Velazco',
    'email' => 'teofilo@payments.com',
    'phone_number' => '4421112233',
    'address' => [
        'line1' => 'Privada Rio No. 12',
        'line2' => 'Co. El Tintero',
        'line3' => '',
        'postal_code' => '76920',
        'state' => 'Querétaro',
        'city' => 'Querétaro.',
        'country_code' => 'MX'
    ]
]);

获取客户

use Perafan\CashierOpenpay\Openpay\Customer as OpenpayCustomer;

$customer = OpenpayCustomer::find('a9ualumwnrcxkl42l6mh');

获取客户列表

use Perafan\CashierOpenpay\Openpay\Customer as OpenpayCustomer;

$customer_list = OpenpayCustomer::all();

// with filters

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$customer_list = OpenpayCustomer::all($filters);

更新客户

use Perafan\CashierOpenpay\Openpay\Customer as OpenpayCustomer;

$customer = OpenpayCustomer::find('a9ualumwnrcxkl42l6mh');
$customer->name = 'Juan';
$customer->last_name = 'Godinez';
$customer->save();

删除客户

use Perafan\CashierOpenpay\Openpay\Customer as OpenpayCustomer;

$customer = OpenpayCustomer::find('a9ualumwnrcxkl42l6mh');
$customer->delete();

卡片

在用户上

添加卡片

$card_data = [
	'holder_name' => 'Teofilo Velazco',
	'card_number' => '4916394462033681',
	'cvv2' => '123',
	'expiration_month' => '12',
	'expiration_year' => '15'
];

$card = $user->addCard($card_data);

// with token

$card_data = [
    'token_id' => 'tokgslwpdcrkhlgxqi9a',
    'device_session_id' => '8VIoXj0hN5dswYHQ9X1mVCiB72M7FY9o'
];

$card = $user->addCard($card_data);

// with address

$address_data = [
    'line1' => 'Privada Rio No. 12',
    'line2' => 'Co. El Tintero',
    'line3' => '',
    'postal_code' => '76920',
    'state' => 'Querétaro',
    'city' => 'Querétaro.',
    'country_code' => 'MX'
];

$card = $user->addCard($card_data, $address_data);

获取卡片

use Perafan\CashierOpenpay\Card;

$card = $user->cards->first;
//or
$card = Card::find(1);

$openpay_card = $card->asOpenpayCard();

获取用户卡片

use Perafan\CashierOpenpay\Card;

$cards = $user->cards;
// or
$cards = Card::where('user_id', $user->id)->get();

从 Openpay 获取用户卡片

use Perafan\CashierOpenpay\Card;
use Perafan\CashierOpenpay\Openpay\Card as OpenpayCard;

$cards = $user->cards;

$openpay_cards = $cards->map(function($card) {
    return $card->asOpenpayCard();
});

// or

$cards = Card::where('user_id', $user->id)->get();

$openpay_cards = $cards->map(function($card) {
    return $card->asOpenpayCard();
});

// or 

$openpay_customer = $user->asOpenpayCustomer();

$openpay_cards = OpenpayCard::all([], $openpay_customer);

// with filters

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_cards = OpenpayCard::all($filters, $openpay_customer);

删除卡片

use Perafan\CashierOpenpay\Card;

$card = $user->cards->first;
//or
$card = Card::find(1);

$openpay_card = $card->asOpenpayCard();
$deleted_card = $openpay_card->delete();

if (!is_array($deleted_card)) {
    //The card was deleted in Openpay
    $card->delete();
}

在商家上

添加卡片

use Perafan\CashierOpenpay\Openpay\Card as OpenpayCard;

$card_data = [
	'holder_name' => 'Teofilo Velazco',
	'card_number' => '4916394462033681',
	'cvv2' => '123',
	'expiration_month' => '12',
	'expiration_year' => '15'
];

$openpay_card = OpenpayCard::add($card_data);

// with token

$card_data = [
    'token_id' => 'tokgslwpdcrkhlgxqi9a',
    'device_session_id' => '8VIoXj0hN5dswYHQ9X1mVCiB72M7FY9o'
];

$openpay_card = OpenpayCard::add($card_data);

// with address

$address_data = [
    'line1' => 'Privada Rio No. 12',
    'line2' => 'Co. El Tintero',
    'line3' => '',
    'postal_code' => '76920',
    'state' => 'Querétaro',
    'city' => 'Querétaro.',
    'country_code' => 'MX'
];

$card_data['address'] = $address_data;

$openpay_card = OpenpayCard::add($card_data);

获取卡片

use Perafan\CashierOpenpay\Openpay\Card as OpenpayCard;

$openpay_card = OpenpayCard::find('k9pn8qtsvr7k7gxoq1r5');

获取卡片列表

use Perafan\CashierOpenpay\Openpay\Card as OpenpayCard;

$openpay_card = OpenpayCard::all();

// with filters

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_card = OpenpayCard::all($filters);

删除卡片

use Perafan\CashierOpenpay\Openpay\Card as OpenpayCard;

$openpay_card = OpenpayCard::find('k9pn8qtsvr7k7gxoq1r5');
$openpay_card->delete();
//Card was not delete on your database, only was deleted in openpay

银行账户

向客户添加银行账户

$bank_data = [
	'clabe' => '072910007380090615',
	'alias' => 'Cuenta principal',
	'holder_name' => 'Teofilo Velazco'
];

$bank_account = $user->addBankAccount($bank_data);

获取银行账户

use Perafan\CashierOpenpay\BankAccount;

$bank_account = $user->bank_accounts->first;
// or
$bank_account = BankAccount::where('user_id', $user->id)->first();

$openpay_bank_account = $bank_account->asOpenpayBankAccount();

获取用户银行账户

use Perafan\CashierOpenpay\BankAccount;

$bank_accounts = $user->bank_accounts;
// or
$bank_accounts = BankAccount::where('user_id', $user->id)->get();

从 Openpay 获取用户银行账户

use Perafan\CashierOpenpay\BankAccount;
use Perafan\CashierOpenpay\Openpay\BankAccount as OpenpayBankAccount;

$bank_accounts = $user->bank_accounts;

$openpay_bank_accounts = $bank_accounts->map(function($bank_account) {
    return $bank_account->asOpenpayBankAccount();
});

// or

$bank_accounts = BankAccount::where('user_id', $user->id)->get();

$openpay_bank_accounts = $bank_accounts->map(function($bank_account) {
    return $bank_account->asOpenpayBankAccount();
});

// or 

$openpay_customer = $user->asOpenpayCustomer();

$openpay_bank_accounts = OpenpayBankAccount::all([], $openpay_customer);

// with filters

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_bank_accounts = OpenpayBankAccount::all($filters, $openpay_customer);

删除银行账户

use Perafan\CashierOpenpay\BankAccount;

$bank_account = $user->bank_accounts->first;
// or
$bank_account = BankAccount::where('user_id', $user->id)->first();

$openpay_bank_account = $bank_account->asOpenpayBankAccount();

$deleted_bank_account = $openpay_bank_account->delete();

if (!is_array($deleted_bank_account)) {
    //The card was deleted in Openpay
    $bank_account->delete();
}

费用

在客户上

对客户进行收费

$charge_data = [
	'source_id' => 'tvyfwyfooqsmfnaprsuk',
	'method' => 'card',
	'currency' => 'MXN',
    'description' => 'Cargo inicial a mi merchant',
    'order_id' => 'oid-00051',
    'device_session_id' => 'kR1MiQhz2otdIuUlQkbEyitIqVMiI16f',
];

$openpay_charge = $user->charge(100, $charge_data);

获取费用

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$openpay_charge = OpenpayCharge::find('a9ualumwnrcxkl42l6mh');

获取每个用户的费用列表

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_customer = $user->asOpenpayCustomer();

$openpay_charge = OpenpayCharge::all($filters, $openpay_customer);

进行捕获

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$capture_data = ['amount' => 150.00];

$openpay_charge = OpenpayCharge::find('a9ualumwnrcxkl42l6mh');

$openpay_charge->capture($capture_data);

退款

// Send charge id as first param 
$charge_id = 'tvyfwyfooqsmfnaprsuk';
$user->refund($charge_id);
//or

$description = 'Reembolso';
$user->refund($charge_id, $description);

//or
$amount = 150.00;
$user->refund($charge_id, $description, $amount);

在商家上

对商家进行收费

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$charge_data = [
	'method' => 'card',
	'source_id' => 'krfkkmbvdk3hewatruem',
	'amount' => 100,
	'description' => 'Cargo inicial a mi merchant',
	'order_id' => 'ORDEN-00071'
];

$openpay_charge = OpenpayCharge::create($charge_data);

获取费用

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$openpay_charge = OpenpayCharge::find('tvyfwyfooqsmfnaprsuk');

获取费用列表

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$openpay_charges = OpenpayCharge::all();

// with filters
$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_charges = OpenpayCharge::all($filters);

进行捕获

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$capture_data = ['amount' => 150.00];

$openpay_charge = OpenpayCharge::find('tvyfwyfooqsmfnaprsuk');
$capture_data->capture($capture_data);

退款

use Perafan\CashierOpenpay\Openpay\Charge as OpenpayCharge;

$refund_data = ['description' => 'Devolución'];

$openpay_charge = OpenpayCharge::find('tvyfwyfooqsmfnaprsuk');
$openpay_charge->refund($refund_data);

转账

进行转账

$transfer_data = [
	'customer_id' => 'aqedin0owpu0kexr2eor',
	'amount' => 12.50,
	'description' => 'Cobro de Comisión',
	'order_id' => 'ORDEN-00061'
];

$openpay_customer = $user->asOpenpayCustomer();
$transfer = $openpay_customer->transfers->create($transfer_data);

获取转账

$openpay_customer = $user->asOpenpayCustomer();
$transfer = $openpay_customer->transfers->get('tyxesptjtx1bodfdjmlb');

获取转账列表

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_customer = $user->asOpenpayCustomer();
$transfer_list = $openpay_customer->transfers->getList($filters);

支付

在客户上

向客户进行支付

$payout_data = [
	'method' => 'card',
	'destination_id' => 'k9pn8qtsvr7k7gxoq1r5',
	'amount' => 1000,
	'description' => 'Retiro de saldo semanal',
	'order_id' => 'ORDEN-00062'
];

$openpay_customer = $user->asOpenpayCustomer();
$payout = $openpay_customer->payouts->create($payout_data);

获取支付

$openpay_customer = $user->asOpenpayCustomer();
$payout = $openpay_customer->payouts->get('tysznlyigrkwnks6eq2c');

获取支付列表

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_customer = $user->asOpenpayCustomer();
$payout_list = $customer->payouts->getList($filters);

费用

挂起...

计划

添加计划

use Perafan\CashierOpenpay\Openpay\Plan as OpenpayPlan;

$plan_data = [
	'amount' => 150.00,
	'status_after_retry' => 'cancelled',
	'retry_times' => 2,
	'name' => 'Plan Curso Verano',
	'repeat_unit' => 'month',
	'trial_days' => '30',
	'repeat_every' => '1',
	'currency' => 'MXN'
];

$openpay_plan = OpenpayPlan::add($plan_data);

获取计划

use Perafan\CashierOpenpay\Openpay\Plan as OpenpayPlan;

$openpay_plan = OpenpayPlan::find('pduar9iitv4enjftuwyl');

获取计划列表

use Perafan\CashierOpenpay\Openpay\Plan as OpenpayPlan;

$openpay_plans = OpenpayPlan::all();
// with filters
$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$openpay_plans = OpenpayPlan::all($filters);

更新计划

use Perafan\CashierOpenpay\Openpay\Plan as OpenpayPlan;

$openpay_plan = OpenpayPlan::find('pduar9iitv4enjftuwyl');
$openpay_plan->name = 'Plan Curso de Verano 2021';
$openpay_plan->save();

删除计划

use Perafan\CashierOpenpay\Openpay\Plan as OpenpayPlan;

$openpay_plan = OpenpayPlan::find('pduar9iitv4enjftuwyl');
$openpay_plan->delete();

获取计划的订阅者列表

use Perafan\CashierOpenpay\Openpay\Plan as OpenpayPlan;

$openpay_plan = OpenpayPlan::find('pduar9iitv4enjftuwyl');

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$subscription_list = $openpay_plan->subscriptions->getList($filters);

订阅

添加订阅

$plan_id = 'pduar9iitv4enjftuwyl';

$subscription = $user->newSubscription($plan_id);

// Add the name of subscription
$options = [
	'trial_end_date' => '2021-01-01', 
	'card_id' => 'konvkvcd5ih8ta65umie'
];

$subscription = $user->newSubscription($plan_id, $options);

// Add the name of subscription
$name = 'plan_verano_2021';

$subscription = $user->newSubscription($plan_id, $options, $name);

检查订阅状态

$name = 'plan_verano_2021';
$user->subscribed($name);

$name_2027 = 'plan_verano_2027';
$user->subscribed($name_2027);

$plan_id = 'pduar9iitv4enjftuwyl';
$user->subscribed($name, $plan_id); 

$user->subscribed($name, 'ptyui9iit40nfwftuwyl'); 
$plans = [
    'pduar9iitv4enjftuwyl',
    'ptyui9iit40nfwftuwyl'
];

$user->subscribedToPlan($plans);

订阅试用

$subscription = $user->subscription();

$subscription->onTrial();

检查用户试用

$subscription_name = 'plan_verano_2027';

$user->onTrial($subscription_name); 

获取订阅

use Perafan\CashierOpenpay\Subscription;
$subscription = $user->subscriptions->first;
// or
$subscription = Subscription::find('s7ri24srbldoqqlfo4vp');

$subscription->asOpenpaySubscription();

获取订阅列表

$openpay = Openpay::getInstance('moiep6umtcnanql3jrxp', 'sk_3433941e467c1055b178ce26348b0fac');

$filters = [
	'creation[gte]' => '2020-01-01',
	'creation[lte]' => '2020-12-31',
	'offset' => 0,
	'limit' => 5
];

$customer = $openpay->customers->get('a9ualumwnrcxkl42l6mh');
$subscriptionList = $customer->subscriptions->getList($filters);

更新订阅

$openpay = Openpay::getInstance('moiep6umtcnanql3jrxp', 'sk_3433941e467c1055b178ce26348b0fac');

$customer = $openpay->customers->get('a9ualumwnrcxkl42l6mh');
$subscription = $customer->subscriptions->get('s7ri24srbldoqqlfo4vp');
$subscription->trial_end_date = '2021-12-31';
$subscription->save();

删除订阅

$openpay = Openpay::getInstance('moiep6umtcnanql3jrxp', 'sk_3433941e467c1055b178ce26348b0fac');

$customer = $openpay->customers->get('a9ualumwnrcxkl42l6mh');
$subscription = $customer->subscriptions->get('s7ri24srbldoqqlfo4vp');
$subscription->delete();

Openpay SDK

许多收银员的对象都是围绕Openpay SDK对象包装的。如果您想直接与Openpay对象交互,您可以使用asOpenpay...方法方便地检索它们。

$openpayCustomer = $user->asOpenpayCustomer();

$openpayCustomer->name = 'Pedro';

$openpayCustomer->save();

$openpaySubscription = $subscription->asOpenpaySubscription();

$subscription->trial_end_date = '2021-12-31';

$openpaySubscription->save();

测试

要开始,请将您的Openpay测试版本的密钥添加到phpunit.xml文件中

<env name="OPENPAY_PUBLIC_KEY" value=""/>
<env name="OPENPAY_PRIVATE_KEY" value=""/>
<env name="OPENPAY_ID" value=""/>

然后您可以在您的环境中运行

$ composer install
$ vendor/bin/phpunit

贡献

有关详细信息和学习清单,请参阅contributing.md

安全性

如果您发现任何与安全相关的问题,请通过电子邮件pedro.perafan.carrasco@gmail.com联系,而不是使用问题跟踪器。

鸣谢

许可

MIT。有关更多信息,请参阅许可文件