shetabit/payment

Laravel 支付网关集成包

v5.8.0 2024-03-07 10:11 UTC

README

Laravel 支付网关

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

这是一个用于支付网关集成的 Laravel 包。该包支持 Laravel 5.8+

赞助我 如果你喜欢这个包 😎 :bowtie:

对于 PHP 集成,你可以使用 shetabit/multipay 包。

此包支持多个驱动程序,如果在你找不到当前驱动程序列表(以下列表)中的驱动程序时,你可以创建自定义驱动程序。

目录

可用驱动程序列表

请通过创建 pull requests 帮助我添加以下网关

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

如果列表中没有,您可以创建自定义驱动程序,请阅读 创建自定义驱动程序 部分。

安装

通过 Composer

composer require shetabit/payment

发布供应商文件

  • 发布配置文件
php artisan vendor:publish --tag=payment-config
  • 发布自定义视图
php artisan vendor:publish --tag=payment-views

配置

如果您使用的是 Laravel 5.5 或更高版本,则不需要添加提供者和别名。(跳到 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,
],

在配置文件中,您可以设置用于所有支付的默认驱动程序。但您也可以在运行时更改驱动程序。

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

// 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;

// Set invoice amount.
$invoice->amount(1000);

// Add invoice details: There are 4 syntax available for this.
// 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:设置发票支付事务 ID
  • getTransactionId:检索支付事务 ID
  • via:设置用于支付发票的驱动程序
  • getDriver:检索驱动程序

购买发票

为了支付发票,我们需要支付事务 ID。我们购买发票以检索事务 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) {
    	// Store transactionId in database.
        // We need the transactionId to verify payment in the future.
	}
)->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) {
    	// Store transactionId in database.
        // We need the transactionId to verify payment in the future.
	}
)->pay()->toJson();

验证支付

当用户完成支付后,银行将他们重定向到您的网站,然后您需要 验证您的支付 以确保 invoice 已经 支付

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

// You need to verify the payment to ensure the invoice has been paid successfully.
// We use transaction id to verify payments
// It is a good practice to add invoice amount as well.
try {
	$receipt = Payment::amount(1000)->transactionId($transaction_id)->verify();

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

    ...
} catch (InvalidPaymentException $exception) {
    /**
    	when payment is not verified, it will throw an exception.
    	We can catch the exception to handle invalid payments.
    	getMessage method, returns a suitable message that can be used in user interface.
    **/
    echo $exception->getMessage();
}

有用方法

  • callbackUrl:可以在运行时更改回调 URL。
    // 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' => [
    'zarinpal' => [...],
    'my_driver' => [
        ... // Your Config Params here.
    ]
]

现在,您必须创建一个用于支付发票的 Driver Map 类。在您的驱动程序中,您只需扩展 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,
]

注意:您必须确保 map 数组的键与 drivers 数组的键相同。

事件

您可以监听两个事件

  • InvoicePurchasedEvent:当发票购买成功时发生(购买发票后完成)。
  • InvoiceVerifiedEvent:当发票成功验证时发生。

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

贡献

请参阅 CONTRIBUTINGCONDUCT 了解详细信息。

安全

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

致谢

许可

MIT 许可证(MIT)。请参阅 许可文件 获取更多信息。

星标历史

Star History Chart