beinmedia/payment

Laravel 包,用于实现 MyFatoorah、Tap、PayPal 支付网关和 PayPal 定期付款。

v1.6.2 2021-11-29 13:13 UTC

README

Latest Version on Packagist Total Downloads Build Status

laravel 包,实现 MyFatoorah、Tap、PayPal 支付网关和 PayPal 定期付款。

功能

  • Laravel 5.7.* | 6.x | 7.x 都受支持。

要求

  • laravel/framework 5.7.*
  • PHP 7.2.5

安装

通过 Composer

$ composer require beinmedia/payment

数据库配置

更新以下 .env 配置

    DB_CONNECTION=mysql
    DB_HOST=add your host
    DB_PORT= add the port
    DB_DATABASE= database name
    DB_USERNAME=database username
    DB_PASSWORD=database password

迁移

 $ php artisan migrate

自动加载

 $ composer dump-autoload

支付网关

为了制作在线支付网关,您需要以下内容

  1. 创建支付网关链接。
  2. 将客户重定向到支付链接。
  3. 用户将付款。
  4. 在创建的支付网关中指定的重定向 URL 接收并验证支付。

PayPal 支付网关

配置

在 .evn 文件中添加 PayPal 凭据,如下例所示

PAYPAL_CLIENT_ID = Ack3DFGTYZSJ_6ypls3tTJQdt64Hp74b5rvykR71XHj0FqvKI4OspcV4dktE2xL-IPBiNoDGko03Mk62

PAYPAL_SECRET = EFZ-UDzdEe-V1QRn15K5TaGgM2Ttb5Z-Rk6dw0WCjrbS4E_6ZkCas4qWqHi5i9SuLvriO_p3KvRAzeSC

PAYPAL_MODE = (sandbox or live)

用法

方法

  • generatePaymentURL($paymentParameters)

此方法将返回用户应重定向以完成支付过程的支付网关 URL。

您需要指定金额、货币、用户在成功付款后应重定向的位置以及用户在付款失败或取消后应重定向的位置。

<?php

use beinmedia\payment\Parameters\PaymentParameters;
use PaypalPayment;

// Create the paymentParameters object
$data=new PaymentParameters();

$data->amount=10;  // Float Amount
$data->currency='USD';  // ISO currency code
$data->trackId= "track id"; //optional - user defined field
$data->returnURL=url('/paypal-check'); // Fully qualified url where the user will be redirected after successful payment.
$data->cancelURL='https://www.example.com'; // Fully qualified url where the user will be redirected after failed payment.

//Getting the payment link where the user should be redirected to
$paymentLink= PaypalPayment::generatePaymentURL($data); 
  • isPayementExecuted() 此方法应在重定向 URL 中调用以验证支付。
<?php

use PaypalPayment;

public function checkPaypalPayment (Request $request){
    if(PaypalPayment::isPaymentExecuted()->status)
        return 'success';
    else
        return 'fail';
}
  • isPayementExecuted($paymentId) 此方法根据特定支付_id 验证支付。
<?php

if(PaypalPayment::isPaymentExecuted("PAYID-L2OH7LA6TM617940X333145E")->status)
    return 'success';
else
    return 'fail';
  • getPayment($payment_id) 此方法根据给定的 payment_id 返回相关的 PayPal 付款详细信息。
use PaypalPayment;

$paypal_payment = PaypalPayment::getPayment($payment_id);

MyFatoorah 支付网关

配置

在 .evn 文件中添加 MyFatoorah API 密钥,如下所示

  • 添加 myFatoorah 的 API 密钥。
MYFATOORAH_API_KEY = 7Fs7eBv21F5xAocdPvvJ-sCqEyNHq4cygJrQUFvFiWEexBUPs4AkeLQxH4pzsUrY3Rays7GVA6SojFCz2DMLXSJVqk8NG-plK-cZJetwWjgwLPub_9tQQohWLgJ0q2invJ5C5Imt2ket_-JAlBYLLcnqp_WmOfZkBEWuURsBVirpNQecvpedgeCx4VaFae4qWDI_uKRV1829KCBEH84u6LYUxh8W_BYqkzXJYt99OlHTXHegd91PLT-tawBwuIly46nwbAs5Nt7HFOozxkyPp8BW9URlQW1fE4R_40BXzEuVkzK3WAOdpR92IkV94K_rDZCPltGSvWXtqJbnCpUB6iUIn1V-Ki15FAwh_nsfSmt_NQZ3rQuvyQ9B3yLCQ1ZO_MGSYDYVO26dyXbElspKxQwuNRot9hi3FIbXylV3iN40-nCPH4YQzKjo5p_fuaKhvRh7H8oFjRXtPtLQQUIDxk-jMbOp7gXIsdz02DrCfQIihT4evZuWA6YShl6g8fnAqCy8qRBf_eLDnA9w-nBh4Bq53b1kdhnExz0CMyUjQ43UO3uhMkBomJTXbmfAAHP8dZZao6W8a34OktNQmPTbOHXrtxf6DS-oKOu3l79uX_ihbL8ELT40VjIW3MJeZ_-auCPOjpE3Ax4dzUkSDLCljitmzMagH2X8jN8-AYLl46KcfkBV
  • 如果您仍在测试且未上线,则将测试模式设置为 true,否则设置为 false。
MYFATOORAH_TEST_MODE = true

用法

  • getMyFatoorahPaymentMethods($currency,$iso_Code)

根据金额,返回您的账户中所有支付方式及其相关费用。

    use MyFatoorahPayment;

    $paymentMethods= MyFatoorahPayment::getMyFatoorahPaymentMethods(10,"KWD");
  • generatePaymentURL($paymentParameters)

此方法将返回用户应重定向以完成支付过程的支付网关 URL。

<?php

use beinmedia\payment\Parameters\PaymentParameters;
use MyFatoorahPayment;

// Create the paymentParameters object
$data=new PaymentParameters();
$data->paymentMethodId=1; // Check the available methods from the table
$data->amount=10; // Amount
$data->trackId= "track id"; //optional - user defined field
$data->currency="KWD"; // optional- default the same as api country currency
$data->name="Alaa"; // optional- Customer name
$data->email="alaa@test.com"; // optional- Customer email
$data->returnURL=url('/fatoorah-check'); // Fully qualified url where the user will be redirected after successful payment.
$data->cancelURL="https://www.beinmedia.com/"; // Fully qualified url where the user will be redirected after failed payment.

//Getting the payment link where the user should be redirected to
$paymentLink = MyFatoorahPayment::generatePaymentURL($data);
  • isPayementExecuted()

此方法应在重定向 URL 中调用以验证支付。

<?php

use MyFatoorahPayment;

public function checkMyFatoorahPayment(Request $request){

    if(MyFatoorahPayment::isPaymentExecuted()->status)
        return ‘success’;
    else
        return ‘fail’;

}
  • isPayementExecuted($invoiceId)

此方法根据特定 invoice_id 验证支付。

<?php

use MyFatoorahPayment;

if(MyFatoorahPayment::isPaymentExecuted(5513941)->status)
    return ‘success’;
else
    return ‘fail’;
  • getPayment($invoice_id)

此方法根据给定的 invoice id 返回相关的 MyFatoorah 付款详细信息。

use MyFatoorahPayment;

$paypal_payment = MyFatoorahPayment::getPayment($payment_id);
  • refund(string $key, string $keyType = 'InvoiceId', $comment="", bool $serviceOnCustomer, bool $refundOnCustomer, float $amount = null)

此方法将根据 $amount 部分或全部退款发票。如果 amount 为 null,则全额退款。

对于 $keyType 的可用选项:'InvoiceId' 或 'PaymentId'

use MyFatoorahPayment;

$refund = MyFatoorahPayment::refund(54432);
  • refundByReference(string $customerReference, $comment="", bool $serviceOnCustomer, bool $refundOnCustomer, float $amount = null)

此方法将通过 customer_reference 退款发票。最后带有相同 customer_reference 的发票将被退款。

use MyFatoorahPayment;

$refund = MyFatoorahPayment::refundByReference("Ali's Invoice 123");

示例退款成功响应

{
refund: {
invoice_id: 918797,
amount: 10,
comment: "test",
service_on_customer: false,
refund_on_customer: false,
refund_id: 14341,
refund_reference: "2021000488",
customer_reference: "25",
updated_at: "2021-08-01 12:28:46",
created_at: "2021-08-01 12:28:46",
id: 6
},
success: true,
errors: null
}

示例退款失败响应

{
success: false,
errors: [
{
Name: "Amount",
Error: "Insufficient Balance for vendor"
}
],
refund: null
}
  • refundsList()

此方法将返回所有退款列表。

use MyFatoorahPayment;

$refunds = MyFatoorahPayment::refundsList();

Tap 支付网关

配置

在 .evn 文件中添加 Tap API 密钥,如下例所示

TAP_API_KEY = sk_test_XKokBfNWv6FIYuTMg5sLPjhJ

Fawry (用于测试模式)

  • 如果您仍在测试且未上线,则将测试模式设置为 true。
FAWRY_TESTING_MODE=true
  • 添加您项目的已发布版本的基 URL(您可以使用 ngrok 进行测试)。
FAWRY_TESTING_PUBLISHED_BASE_URL=https://789fbf71.ngrok.io

用法

Fawry 网关

法瑞支付结构不同,支付验证是异步进行的。您需要设置postURL,一旦支付完成,您将收到通知。无需设置redirectURL。一旦执行支付,Tap将请求提供的post URL,您需要调用isPayementExecuted()方法来验证支付并检查支付状态。

方法

  • generatePaymentURL($paymentParameters)

此方法返回用户应跳转以进行支付的URL。它可以用于信用卡和借记卡,但不能用于直接支付。对于法瑞支付,此方法返回订单号而不是支付URL,用户将使用此号码在任何法瑞中心支付。

<?php

use beinmedia\payment\Parameters\PaymentParameters;
use TapPayment;

//for fawry add postURL only
//for other methods add redirectURL only

$data=new PaymentParameters();

$data->email="alaanaser95.95@gmail.com"; // Customer email
$data->name="Alaa"; //Customer email
$data->countryCode="965";
$data->phoneNumber="65080631";
$data->trackId= "track id"; //optional - user defined field
$data->amount=10; // float amount
$data->description="dfghjk";
$data->paymentMethodId="src_eg.fawry";
$data->currency="EGP"; // Iso currency
$data->destination_id = '1235'; //the destination_id returned from create business (used for multivendor)
$data->transfer_amount = 9; // the amount that will be transfered to the business in case destination_id is specified; 

// For fawry only - To get notification once the payment is completed (Asyncronous payment)
$data->postURL=url('/api/fawry-check'); // Fully qualified url (Only Post method routs are allowed).

// For other methods only, not for fawry
$data->returnURL=url("tap-check"); // Fully qualified url where the user will be redirected after successful payment.

//Getting the payment link where the user should be redirected to
$paymentLink = TapPayment::generatePaymentURL($data);
  • ChargeCard()

此方法返回支付状态、卡ID、充值ID和客户ID。它可以用于使用Tap card.js库直接支付为信用卡充值。

<?php

use beinmedia\payment\Parameters\PaymentParameters;
use TapPayment;

        //for fawry add postURL only
        //for other method add redirectURL only
        $data=new PaymentParameters();
        $data->email="alaanaser95.95@gmail.com";
        $data->name="Alaa";
        $data->returnURL=url("tap-check");
        $data->countryCode="965";
        $data->phoneNumber="65080631";
        $data->amount=10;
        $data->description="dfghjk";
        $data->paymentMethodId="tok_Ck8tJ1311012ntXJ527473";// the one time token created with tap card.js library
        $data->currency="KWD";
        $data->trackId="1234";
        $data->destination_id = '1234';
        $data->transfer_amount = 9;

        //Charge the credit card and get the response
        $paymentLink = TapPayment::ChargeCard($data);

/*
Response Eample
{
"card_id" : "card_576789",
"customer_id" : "cus_43465789",
"charge_id" : "ch_5476769",
"status" : true 
}
*/
  • isPayementExecuted()

此方法应在重定向 URL 中调用以验证支付。

<?php

use TapPayment;

public function checkTapPayment (Request $request){
    if( TapPayment::isPaymentExecuted()->status)
        return ‘success’;
    else
        return ‘fail’;
}

Tap 定期支付

如果您想创建订阅,定期以特定金额向客户信用卡收费,您需要创建订阅。订阅仅适用于信用卡('visa'、'master'、'amex')。

您可以从chargeCard()方法中获取card_id和customer_id。

方法

  • createSubscription()
use beinmedia\payment\Services\TapGateway;
use beinmedia\payment\Parameters\SubscriptionCharge;
use beinmedia\payment\Parameters\SubscriptionParameters;
use beinmedia\payment\Parameters\SubscriptionTerm;

public function createSubscription(){
        $term = new SubscriptionTerm();
        $term->interval = "DAILY"; //("DAILY","YEARLY","MONTHLY",...etc)
        $term->period = 10; //How many times you want to charge the customer card
        $term->from = "2020-11-12 16:08:00"; "the start time for the charge
        $term->due = 0; 
        $term->auto_renew = true; //true if you want to renew the subscription automatically
        $term->timezone = "Asia/Kuwait"; //the timezone for which the start time for ythe charge is specified

        $charge = new SubscriptionCharge();
        $charge->amount = 10; //thre amount to be charged
        $charge->currency = "KWD"; //the currency of charge amount
        $charge->description = "This is a test subscription";
        $charge->metadata->track_id = "123456789910"; //A custom reference_id 
        $charge->reciept->email = true; //optional
        $charge->reciept->sms = true; //optional
        $charge->customer->id = 'cus_TS024820201200n5X50811060'; //customer_id returned from ChargeCard() method
        $charge->source->id = 'card_CFlTu1311012JanD527931'; //card_id returned from ChargeCard() method
        $charge->post->url = 'https://3b2429fb7e8b.ngrok.io/api/handle'; // post url where you want to be notified once a periodic payment is done.

        //Create subscription and get the subscription_id and status
        $data = new SubscriptionParameters($term,$charge);
        $response = app(TapGateway::class)->createSubscription($data);
        return response()->json(['response'=>$response]);
    }

/*
Response Eample
{
"status" : "active",
"id" : "sub_43465789",
}
*/
  • verifySubscriptionPayment()

在创建订阅时指定的post URL上调用此方法以验证订阅的支付。

use beinmedia\payment\Services\TapGateway;

public function handleRecurring(){
        $response = app(TapGateway::class)->verifySubscriptionPayment();

        //you can call this for more verificattion:
        //$response = app(TapGateway::class)->isPaymentExecuted();

        if($response->status == true){
            return 'success';
        }
        return 'failed';
    }
  • cancelSubscription()
    public function cancelSubscription(){
        return app(TapGateway::class)->cancelSubscription('sub_Xr8s3820200900r5L51211982')]);
    }

TAP 多商家(订阅)

配置

在.env文件中设置以下内容

TAP_MARKETPLACE_API_KEY = sk_test_fEZYI3X1P7865rtsoGpbvw4qBm

可用方法

  • getSectors()

获取Tap支持的所有行业列表,以便在创建业务时添加其中一个行业ID。

    public function getSectors(){
        return app(TapGateway::class)->getSectors($fileParameters);
    }
  • createFile()
    public function createFile(){
        $filename = time().'.'.request('file')->getClientOriginalExtension();
        request('file')->move('storage', $filename);
        $filePath = "storage/$filename";
        $purpose = 'identifcation_document';
        $fileParameters = new FileParameters($filePath, $filename, $purpose);
        return app(TapGateway::class)->createFile($fileParameters);
    }
  • createBusiness()

添加新业务详情,以便任何与业务destination_id创建的充值将直接转入业务银行账户。

use beinmedia\payment\Services\TapGateway;

    public function createBusiness(){
        $civil_id = new \stdClass();
        $civil_id->type = 'civil id';
        $civil_id->issuing_country = 'KW';
        $civil_id->issuing_date = '2020-01-01';
        $civil_id->expiry_date = '2021-01-01';
        $civil_id->images = ['file_773153834221826048']; //the file_id returned from createFile method as array 
        $civil_id->number = '295102500437'; //civil_id number
        $contact_person = new ContactPerson('Alaa','Naser',new Phone('965','65080631'),'alaanser95.95@gmail.com', [$civil_id]);

        $authorization = new \stdClass();
        $authorization->type = 'authorized_signature';
        $authorization->issuing_country = 'KW';
        $authorization->issuing_date = '2020-01-01';
        $authorization->expiry_date = '2021-01-01';
        $authorization->images = ['file_773150399938293760']; //the file_id returned from createFile method as array
        $authorization->number = '295102500437'; //authorized signature number

        $license = new \stdClass();
        $license->type = 'license';
        $license->issuing_country = 'KW';
        $license->issuing_date = '2020-01-01';
        $license->expiry_date = '2021-01-01';
        $license->images = ['file_773155798586355712']; //the file_id returned from createFile method as array 
        $license->number = '295102500437'; //commercial license number

        $parameters = new BusinessParameters();
        $parameters->business_name = 'test12121';
        $parameters->type = 'corp';
        $parameters->business_legal_name = 'test company for testing21212';
        $parameters->business_country = 'KW';
        $parameters->iban = 'erj54r73658647246928724'; //if iban is not added then swift_code and account_number are required
        $parameters->swift_code = '1234567890'; //optinal if iban is provided
        $parameters->account_number = 'acc_12345567890'; //optional if iban is provided
        $parameters->contact_person = $contact_person;
        $parameters->sector = ['sector_Vi2Dy828EgUeDVJ']; //returned from getSetors() method
        $parameters->website = 'https://oktabletmenu1.com';
        $parameters->documents = [$authorization, $license];

        return app(TapGateway::class)->createBusiness($fileParameters);

Paypal 定期支付

配置

在.env文件中设置以下内容

- Add your webhook URL where you will get notified once a subscrbtion is canceled or recurring payment is completed (you can use ngrok for testing. 
``` bash
PAYPAL_RECURRING_WEBHOOK_URL=https://b2015d91.ngrok.io/webhook

创建webhook

此webhook只需在实时环境下创建一次,以便允许包接收Paypal的通知。

 $ php artisan create:webhook

如果您使用ngrok进行测试,您需要重置env文件中的相关数据,并且每7小时重新创建webhook。

用法

为了创建定期支付的协议,您需要以下内容

  1. 创建一个要分配给协议的计划。(多个协议可以分配给同一个计划)
  2. 创建协议并获取用户应跳转以接受此协议的批准链接。
  3. 执行协议以处理协议接受并验证协议接受。
  4. 每次任何协议的支付完成或任何协议取消时,您都会收到post通知,以便您可以授予或撤销支付者的许可。

可用方法

  • createPlan()
<?php

use beinmedia\payment\Parameters\PlanParam;
use PaypalRecurring;

//create planParam object
$planParam=new PlanParam();

$planParam->planName='Premium Package';
$planParam->description='Get Full access to all our features';
$planParam->amount=10;
$planParam->returnURL=url("/recurring-execute"); // Fully qualified url where the user will be redirected after successful payment.
$planParam->cancelURL="https://www.tapcom.com/"; // // Fully qualified url where the user will be redirected after failed payment.

//create A plan
$createdPlanObject= PaypalRecurring::createPlan($planParam);
  • createAgreement($plan_id, $agreement_name, $agreement_description, $payer_info, $reference_id))
<?php

use PaypalRecurring;

 $payer_info = new PayerInfoParameters();
        $payer_info->email='alaanaser95.95@gmail.com';
        $payer_info->first_name = 'Alaa';
        $payer_info->last_name = 'Naser';
        $payer_info->payer_id = '987654321';
// Generate agreement url where the user should be redirected to
$agreementLink = PaypalRecurring::createAgreement('P-3D407875MD555251WQYZQOJA','Alaa','MyAgreement', $payer_info, "123456789");
  • executeAgreement()
<?php

use PaypalRecurring;

public function executeAgreement(Request $request){

    if(PaypalRecurring::executeAgreement() instanceof Agreement)
            return 'yes';
    return 'No';
}
  • cancelAgreement($agreement_id)
<?php

use PaypalRecurring;

public function cancelAgreement(Request $request){

    return PaypalRecurring::cancelAgreement('I-975S8RWXLGMU');
}
  • cancelAgreement($agreement_id)
<?php

use PaypalRecurring;

public function cancelAgreement(Request $request){

    return PaypalRecurring::cancelAgreement('I-975S8RWXLGMU');
}
  • checkAgreementPayed($agreement_id)
<?php

use PaypalRecurring;

public function cancelAgreement(Request $request){

    return PaypalRecurring::checkAgreementPayed('I-975S8RWXLGMU');
}

获取支付列表

在某些时候,您可能需要获取所有完成的支付以进行统计。该包通过getAllPayments()方法提供此功能。

用法

use Payments;

//returns all completed payments through Tap, Myfatoorah, paypal and paypal recurring payments.

$all_payments = Payments::getAllPayments();

示例

isPaymentExecuted();

    {
        "status" : true, //true => payment approved, false => payment declined
        "track_id": "track id"
    }

Fawry

isPaymentExecuted();

    {
        "tap_id" : "chg_Nj545620201224Zq450303159" ,
        "status" : true, //true => payment approved, false => payment declined
        "track_id": "track id"
    }
  • Paypal 定期支付

一旦定期支付完成

    {
        "event_type" : "PAYMENT.SALE.COMPLETED" ,
        "agreement_id" : "I-PE7JWXKGVN0R",
        "payment_id" : "80021663DE681814L"
    }

一旦定期支付取消

    {
        "event_type" : "BILLING.SUBSCRIPTION.CANCELLED" ,
        "agreement_id" : "I-PE7JWXKGVN0R"
    }

信用