thepublicgood/payfast

简单的PayFast集成

v0.5.0 2024-07-15 13:09 UTC

README

Run Tests

Payfast

一个简单的PayFast库。

安装

使用命令行通过composer安装PayFast库

composer require thepublicgood/payfast

用法

PayFast目前没有在生产环境中提供现场支付解决方案。有一个beta服务可用,但这个库不支持该服务。当服务投入生产并在沙盒环境中添加支持后,我会更新这个库。在此之前,这个库只支持PayFast自定义集成选项。

商家

所有交易都需要一个商家对象。PayFast会提供你的商家ID和商家密钥。你还需要登录PayFast账户并设置一个密码短语。尽管PayFast不要求,但这个库要求设置密码短语。

Merchant类创建一个新的商家对象,并传入你的认证数据。你可以在商家实例上设置返回URL、取消URL和通知URL。你希望将这些都设置为你的网站上的端点。

$merchant = new \TPG\PayFast\Merchant('MERCHANT_ID', 'MERCHANT_KEY', 'PASSPHRASE');

$merchant
    ->setReturnUrl($returnUrl)
    ->setCancelUrl($cancelUrl)
    ->setNotifyUrl($notifyUrl);

由于PayFast需要访问这些URL,在测试期间,访问你的测试环境可能会有所帮助。如果你需要这个,请查看Expose

客户

不需要客户即可进行任何交易。但是,如果你想要设置这些数据,你可以通过创建一个新的Customer实例并设置名称、电子邮件和手机号码来做到这一点。如果用户在PayFast注册了账户,这将有助于提高客户体验。

$customer = new \TPG\PayFast\Customer();

$customer
    ->setName('First', 'Last')
    ->setEmail('email@test.com')
    ->setCellNumber('1234567890');

交易

交易是所有魔法发生的地方。交易类的构造函数接受三个参数:商家实例、交易的金额(南非分)和商品名称。名称可以是交易的某个参考,这样用户就可以在PayFast网站上看到他们正在支付什么。

$transaction = new \TPG\PayFast\Transaction($merchant, 10000, 'Item Name');

一旦你有了交易对象,你可以进行一些更改

$transaction
    ->setCustomer($customer)                  // Set a customer
    ->setMerchantPaymentId('PAYID123').       // A payment reference
    ->setDescription('Item Description')      // A payment description
    ->setCustomIntegers([                     // Up to 5 custom integers
        1,
        2,
        3,
        4,
        5,
    ])
    ->setCustomStrings([                     // Up to 5 custom strings
        'S1',
        'S2',
        'S3',
        'S4',
        'S5'
    ])
    ->setEmailConfirmation(true)            // Where to send email confirmations
    ->setEmailConfirmationAddress('email@test.com')  // The confirmation email
    ->setPaymentMethod(\TPG\PayFast\PaymentMethod::ALL); // Payment method

支付方式只是限制你接受哪些支付方式的一种方式。在大多数情况下,你可能想要PaymentMethod::ALL,但也有其他几种。

PaymentMethod::ALL;  // All payment methods allowed
PaymentMethod::CC;   // Credit Cards
PaymentMethod::DC;   // Debit cards
PaymentMethod::EFT;  // EFT
PaymentMethod::MP;   // MasterPass
PaymentMethod::MC;   // Mobicred
PaymentMethod::SC;   // SCode

无法允许这些的组合。要么是全部,要么是其中之一。

创建表单

创建一个新的PayFast实例,并传入交易。现在我们可以生成一个简单的HTML表单,可以将其放置在视图中。表单ID始终是#payfast_form,因此你可以使用一些JavaScript来引用它,或者你可以传递一个整数值到form()方法,在经过指定秒数后自动提交表单。

$payfast = new \TPG\PayFast\PayFast($transaction);

$submissionDelay = 10; // seconds to wait before automatically submitting the form.
$form = $payfast->form($submissionDelay);

echo $form;

如果你不提供延迟,你需要自己提交表单。请记住,你不应该将此表单显示给最终用户,并且所有表单字段都是“隐藏”类型。

验证ITN

一旦交易已提交给PayFast并且你设置了通知URL,你可以使用ItnValidator类来验证PayFast返回的ITN。PayFast建议立即设置一个标题,然后继续验证过程。

namespace App\Http\Controllers;

class PayFastController
{
    public function webhook(Request $request)
    {
        // Create a new validator
        $validator = new \TPG\PayFast\ItnValidator($request->input());
        
        // From the PayFast docs... Send a 200 response right away...
        $validator->flush();
    
        // You have access to all the response data through the `PayfastResponse` class.
        $response = $validator->response();
        
        $mpid = $response->merchantPaymentId();  // Original payment ID set on the transaction
        $pfid = $response->payFastPaymentId();   // PayFast's payment ID
        $name = $response->name();           // Item name or order number
        $description = $response->description();    // Item or order description
        $gross = $response->amountGross();        // Total charge
        $fee = $response->amountFee();          // Payfast fee amount
        $net = $response->amountNet();          // Net amount
        $integer = $response->customIntegers();    // Array of custom integers
        $string = $response->customStrings();     // Array of custom strings
        
        $firstName = $response->customer()->firstName();      // Customers first name
        $lastName = $response->customer()->lastName();       // Customers last name
        $emailAddress = $response->customer()->emailAddress();   // Customers email address
        $cellNumber = $response->customer()->cellNumber();     // Customers cell number
        
        $signature = $response->signature();                  // Signature for validation
        
        //--------------------
        
        // To validate the transaction, first ensure the transaction is COMPLETE:
        if ($response->paymentStatus() !== \TPG\PayFast\PaymentStatus::COMPLETE) {
            // incomplete...
        }
        
        // Then `validate()` will return true or throw an exception
        $valid = $validator->validate(10000, $passphrase, $request->ip());
        
        if (!$valid) {
            echo $validator->error();
        }
        
        // validated!
    }
}

订阅

订阅的启动方式与标准交易相同。只需在Transaction实例上添加对subscription()的调用即可

$transaction = new Transaction($merchant, 10000);
$transaction->subscription();

这将确保交易作为周期性交易传递给PayFast。subscription方法还接受一些选项来自定义订阅。你可以指定频率、周期数和计费日期

$transaction->subscription(
    Transaction::SUBSCRIPTION_FREQUENCY_QUARTERLY,  // frequency
    10,                                             // number of cycles
    new DateTime('tomorrow'),                       // Billing start date
);

PayFast支持四种频率选项

$monthly = Transaction::SUBSCRIPTION_FREQUENCY_MONTHLY;  // default
$quarterly = Transaction::SUBSCRIPTION_FREQUENCY_QUARTERLY;
$biannually = Transaction::SUBSCRIPTION_FREQUENCY_BIANNUALLY;
$annually = Transaction::SUBSCRIPTION_FREQUENCY_ANNUALLY;

参数 cycles 默认为0,表示无限。订阅将继续,直到被取消。

提交交易后,您可以在 ItnValidator 实例上使用 token() 方法来获取交易的令牌引用,然后可以使用该引用来管理该订阅

$validator = new ItnValidator($request->input());

if ($validator->validate(10000, 'passphrase', $request->ip()) {
    $token = $validator->token();
}

从 PayFast 获取订阅

您可以使用 Subscription 类来获取任何订阅的详细信息。将 Merchant 实例作为构造函数的第一个参数,订阅令牌作为第二个参数,然后调用 fetch 方法

$subscription = new Subscription($merchant, $token);
$subscription->fetch();

$data = $subscription->toArray();

Subscription 类提供了一些功能,可用于管理任何订阅

暂停/恢复订阅

您可以暂停任何数量的周期,但默认情况下订阅只会暂停1个周期。下一个计费周期将被跳过。您可以使用 Subscription 对象上的 runDate 方法来获取下一个计费日期。

$subscription->pause();

$subscription->fetch()->runDate();  // Will skip the next billing date

//---------------------------------------

$subscription->pause(2);

$subscription->fetch()->runDate(); // Will skip the next two billing dates

请注意,PayFast 不允许您更改这里暂停的周期数。您需要先 unpause 然后再用新的周期数 pause

要恢复订阅,只需调用 unpause() 方法

$subscription->unpause();

要检查订阅是否已暂停,paused() 方法将返回 true。

$subscription->pause();
$subscription->paused();  // true

取消订阅

要取消订阅,只需调用 cancel() 方法

$subscription->cancel();
$subscription->cancelled();  // true

PayFast 保留已取消交易的信息,因此即使您从已取消的交易中获取数据,您仍然会收到该交易数据,但 cancelled() 将返回 true

沙箱

PayFast 提供了一个简单的沙箱,可以测试交易。沙箱位于 https://sandbox.payfast.co.za。为了使用沙箱,您需要告诉库您正在进行测试。您可以在创建表单时通过在 Payfast 实例上调用 testing() 方法来实现

$payfast = new PayFast($transaction);

$form = $payfast->testing()->form();

这将确保请求被发送到沙箱,而不是实际的 PayFast 终端。对于 ItnValidator 也是如此

$validator = new ItnValidator($request->input());
$valid = $validator->testing()->validate(10000, $passphrase, $request->ip());

并且在管理订阅时

$subscription = new Subscription($merchant, 'TOKEN');
$subscription->testing()->pause();