Skip to content

Latest commit

 

History

History
510 lines (389 loc) · 15.1 KB

README-ZH.md

File metadata and controls

510 lines (389 loc) · 15.1 KB

Laravel 支付网关

Software License Latest Version on Packagist Total Downloads on Packagist StyleCI Maintainability Quality Score

这是一个用于整合支付网关的Laravel包。这个包依赖 Laravel 5.8+.

捐赠我 如果你喜欢这个包:sunglasses: :bowtie:

For PHP integration you can use shetabit/multipay package.

此软件包可用于多个驱动程序,如果在当前驱动程序列表中找不到驱动程序,则可以创建它们

目录

可用驱动列表

您可以通过pull requests 帮助我创建更多的网关

  • stripe
  • authorize
  • 2checkout
  • braintree
  • skrill
  • payU
  • amazon payments
  • wepay
  • payoneer
  • paysimple

如果找不到你需要的,您可以创建你自己的驱动,阅读创建自定义驱动部分,可以了解更多

安装

通过 Composer

$ composer require shetabit/payment

配置

如果你使用Laravel 5.5或更高版本,你不需要手动设置 provideralias,可以直接看b步骤

a. 在你的 config/app.php 文件中,添加如下两行

// In your providers array.
'providers' => [
    ...
    Shetabit\Payment\Provider\PaymentServiceProvider::class,
],

// In your aliases array.
'aliases' => [
    ...
    'Payment' => Shetabit\Payment\Facade\Payment::class,
],

b. 然后运行 php artisan vendor:publish 来发布 config/payment.php 文件到你的项目中

在配置文件中,您可以将 default设置项设置为你希望的付款方式。但也可以在运行时更改驱动。

选择要在应用程序中使用的网关。然后将其设为默认驱动程序,这样就不必在任何地方都指定它。但是,您也可以在一个项目中使用多个网关。

// Eg. if you want to use zarinpal.
'default' => 'zarinpal',

然后在驱动数组中填充该网关的凭据。

'drivers' => [
    'zarinpal' => [
        // Fill in the credentials here.
        'apiPurchaseUrl' => 'https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json',
        'apiPaymentUrl' => 'https://www.zarinpal.com/pg/StartPay/',
        'apiVerificationUrl' => 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json',
        'merchantId' => '',
        'callbackUrl' => 'http://yoursite.com/path/to',
        'description' => 'payment in '.config('app.name'),
    ],
    ...
]

如何使用

您的 Invoice 包含您的付款详细信息,因此我们首先将讨论 Invoice 类。

使用费用清单进行工作

在做任何事情之前,您需要使用 Invoice 类来创建费用清单。

像下面这样,在你的代码中使用费用清单:

// At the top of the file.
use Shetabit\Multipay\Invoice;
...

// Create new invoice.
$invoice = new Invoice;

// 设置清单金额.
$invoice->amount(1000);

// 给清单添加详情: 这里展示了四种语法.
// 1
$invoice->detail(['detailName' => 'your detail goes here']);
// 2 
$invoice->detail('detailName','your detail goes here');
// 3
$invoice->detail(['name1' => 'detail1','name2' => 'detail2']);
// 4
$invoice->detail('detailName1','your detail1 goes here')
        ->detail('detailName2','your detail2 goes here');

可用方法:

  • uuid: 设置一个清单的唯一id
  • getUuid: 获取清单的当前唯一id
  • detail: 给清单添加自定义信息
  • getDetails: 获取所有的详细信息
  • amount: 设置一个清单金额
  • getAmount: 获取清单金额
  • transactionId: 设置支付交易单号
  • getTransactionId: 获取支付交易单号
  • via: 设置我们用来支付清单的驱动
  • getDriver: 获取驱动

获取支付清单

为了支付清单,我们需要付款交易ID:

// At the top of the file.
use Shetabit\Multipay\Invoice;
use Shetabit\Payment\Facade\Payment;
...

// Create new invoice.
$invoice = (new Invoice)->amount(1000);

// Purchase the given invoice.
Payment::purchase($invoice,function($driver, $transactionId) {
	// We can store $transactionId in database.
});

// Purchase method accepts a callback function.
Payment::purchase($invoice, function($driver, $transactionId) {
    // We can store $transactionId in database.
});

// You can specify callbackUrl
Payment::callbackUrl('http://yoursite.com/verify')->purchase(
    $invoice, 
    function($driver, $transactionId) {
    	// We can store $transactionId in database.
	}
);

支付

在获取支付单后,我们可以跳转到第三方支付机构的页面

// At the top of the file.
use Shetabit\Multipay\Invoice;
use Shetabit\Payment\Facade\Payment;
...

// Create new invoice.
$invoice = (new Invoice)->amount(1000);
// Purchase and pay the given invoice.
// You should use return statement to redirect user to the bank page.
return Payment::purchase($invoice, function($driver, $transactionId) {
    // Store transactionId in database as we need it to verify payment in the future.
})->pay()->render();

// Do all things together in a single line.
return Payment::purchase(
    (new Invoice)->amount(1000), 
    function($driver, $transactionId) {
        // 把交易ID保存到数据库.
        // 在接下来的付款中,我们需要验证交易ID
	}
)->pay()->render();

// Retrieve json format of Redirection (in this case you can handle redirection to bank gateway)
return Payment::purchase(
    (new Invoice)->amount(1000), 
    function($driver, $transactionId) {
        // 把交易ID保存到数据库.
        // 在接下来的付款中,我们需要验证交易ID
	}
)->pay()->toJson();

验证付款

当用户完成付款后,支付机构会将其重定向到您的网站,然后您需要验证您的付款,以确保清单支付

// At the top of the file.
use Shetabit\Payment\Facade\Payment;
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
...

// 您需要验证支付机构的回传数据,以确保付款成功
// 我们需要使用交易ID来验证
// 使用交易金额来验证,也是一个很好的方法
try {
	$receipt = Payment::amount(1000)->transactionId($transaction_id)->verify();

    // You can show payment referenceId to the user.
    echo $receipt->getReferenceId();

    ...
} catch (InvalidPaymentException $exception) {
    /**
    	如果未验证付款,则会引发异常。

我们可以抓住异常处理无效付款。

getMessage方法,返回可在用户界面中使用的适当消息。
    **/
    echo $exception->getMessage();
}

有用的方法

  • callbackUrl: 使用它可以在运行时改变回调地址.
    // At the top of the file.
    use Shetabit\Multipay\Invoice;
    use Shetabit\Payment\Facade\Payment;
    ...
    
    // Create new invoice.
    $invoice = (new Invoice)->amount(1000);
    
    // Purchase the given invoice.
    Payment::callbackUrl($url)->purchase(
        $invoice, 
        function($driver, $transactionId) {
        // We can store $transactionId in database.
    	}
    );
  • amount: 你可以设置一个清单的金额
    // At the top of the file.
    use Shetabit\Multipay\Invoice;
    use Shetabit\Payment\Facade\Payment;
    ...
    
    // Purchase (we set invoice to null).
    Payment::callbackUrl($url)->amount(1000)->purchase(
        null, 
        function($driver, $transactionId) {
        // We can store $transactionId in database.
    	}
    );
  • via: 在运行中更改支付方式
    // At the top of the file.
    use Shetabit\Multipay\Invoice;
    use Shetabit\Payment\Facade\Payment;
    ...
    
    // Create new invoice.
    $invoice = (new Invoice)->amount(1000);
    
    // Purchase the given invoice.
    Payment::via('driverName')->purchase(
        $invoice, 
        function($driver, $transactionId) {
        // We can store $transactionId in database.
    	}
    );
  • config: 在运行中更改驱动的配置信息
    // At the top of the file.
    use Shetabit\Multipay\Invoice;
    use Shetabit\Payment\Facade\Payment;
    ...
    
    // Create new invoice.
    $invoice = (new Invoice)->amount(1000);
    
    // Purchase the given invoice with custom driver configs.
    Payment::config('mechandId', 'your mechand id')->purchase(
        $invoice,
        function($driver, $transactionId) {
        // We can store $transactionId in database.
    	}
    );
    
    // Also we can change multiple configs at the same time.
    Payment::config(['key1' => 'value1', 'key2' => 'value2'])->purchase(
        $invoice,
        function($driver, $transactionId) {
        // We can store $transactionId in database.
    	}
    );

创建自定义驱动:

首先必须在drivers数组中添加驱动程序的名称,还可以指定所需的任何配置参数。

'drivers' => [
    'zarinpal' => [...],
    'my_driver' => [
        ... // Your Config Params here.
    ]
]

现在您必须创建一个将用于支付清单的驱动程序映射类。 在你的驱动中,你必须继承 Shetabit\Payment\Abstracts\Driver.这个类

例如,你创建了这样一个类: App\Packages\PaymentDriver\MyDriver

namespace App\Packages\PaymentDriver;

use Shetabit\Multipay\Abstracts\Driver;
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
use Shetabit\Multipay\{Contracts\ReceiptInterface, Invoice, Receipt};

class MyDriver extends Driver
{
    protected $invoice; // Invoice.

    protected $settings; // Driver settings.

    public function __construct(Invoice $invoice, $settings)
    {
        $this->invoice($invoice); // Set the invoice.
        $this->settings = (object) $settings; // Set settings.
    }

    // Purchase the invoice, save its transactionId and finaly return it.
    public function purchase() {
        // Request for a payment transaction id.
        ...
            
        $this->invoice->transactionId($transId);
        
        return $transId;
    }
    
    // Redirect into bank using transactionId, to complete the payment.
    public function pay() {
        // It is better to set bankApiUrl in config/payment.php and retrieve it here:
        $bankUrl = $this->settings->bankApiUrl; // bankApiUrl is the config name.

        // Prepare payment url.
        $payUrl = $bankUrl.$this->invoice->getTransactionId();

        // Redirect to the bank.
        return redirect()->to($payUrl);
    }
    
    // Verify the payment (we must verify to ensure that user has paid the invoice).
    public function verify(): ReceiptInterface {
        $verifyPayment = $this->settings->verifyApiUrl;
        
        $verifyUrl = $verifyPayment.$this->invoice->getTransactionId();
        
        ...
        
        /**
			Then we send a request to $verifyUrl and if payment is not valid we throw an InvalidPaymentException with a suitable message.
        **/
        throw new InvalidPaymentException('a suitable message');
        
        /**
        	We create a receipt for this payment if everything goes normally.
        **/
        return new Receipt('driverName', 'payment_receipt_number');
    }
}

创建该类后,必须在 payment.php 配置文件的 map 部分中指定它。

'map' => [
    ...
    'my_driver' => App\Packages\PaymentDriver\MyDriver::class,
]

Note:- 必须确保 map 数组的键与 drivers 数组的键相同。

事件

你可以监听两个事件

  • InvoicePurchasedEvent: 在获取清单后执行
  • InvoiceVerifiedEvent: 在验证交易成功后执行

Change log

请查看 CHANGELOG 来获取更多关于版本更新的信息

贡献

请查看 CONTRIBUTINGCONDUCT 获取更多详细信息

安全

如果您发现任何与安全相关的问题,请发送电子邮件至[email protected],而不要使用issue。

信誉

License

The MIT License (MIT). Please see License File for more information.