dhavalsagepaypi/sagepay-pi

Opayo PI(原名 SagePay PI)PHP API,使用 PSR7、PSR17、PSR18 标准。

v1.0.2 2024-04-08 10:59 UTC

This package is auto-updated.

Last update: 2024-09-08 12:11:47 UTC


README

SagePayPi (Opayo)

受以下项目启发 sagepay-pi

更新

错误响应中存在问题的解决。

Opayo PI PHP 客户端

pipeline status coverage report Licence MIT PHPStan - Level 9

Opayo PI(原名 Sagepay PI)支付 API 的 PHP 客户端。

安装

composer require dhavalsagepaypi/sagepay-pi

您还需要提供以下包

  • psr/http-message-implementation(PSR7)
  • psr/http-factory-implementation(PSR17)
  • psr/http-client-implementation(PSR18)

使用前

通常我建议查看 tests/ 目录和 Opayo PI API 参考

该库的目标是在实现层面上尽可能接近 API 文档。

该库使用的每个接口都有相同命名空间中的默认实现。

方法参考

API 端点和它们的库方法

获取商户会话密钥

POST /merchant-session-keys/
Lumnn\SagePayPi\SagePayPi::getMerchantSessionKey(): string

如果密钥未过期或已使用,将返回之前创建的密钥。由于库处理生成和身份验证,因此不一定需要。

验证 MSK

GET /merchant-session-keys/{merchantSessionKey}
Lumnn\SagePayPi\SagePayPi::validateMerchantSessionKey(string $merchantSessionKey): bool

将返回一个布尔值,表示密钥是否有效。

创建卡标识符

POST /card-identifiers
Lumnn\SagePayPi\Card\Cards::createIdentifier(CardDetailsInterface $card): CardIdentifierInterface

链接可重用安全代码

POST /card-identifiers/{cardIdentifier}/security-code
Lumnn\SagePayPi\Card\Cards::linkReusableSecurityCode(CardIdentifierInterface $cardIdentifier, string $securityCode): void

创建交易(支付/退款/重复)

POST /transactions
Lumnn\SagePayPi\Transacton\Transactions::create(TransactionRequestInterface $transaction, array $options = []): AbstractResponse

根据 $transaction 类,这将创建支付、退款或重复交易。

  • @param $transaction - 可以是以下之一

    • Lumnn\SagePayPi\Transaction\PaymentRequestInterface
    • Lumnn\SagePayPi\Transaction\RefundRequestInterface
    • Lumnn\SagePayPi\Transaction\RepeatRequestInterface
  • @param $options['save_card'] - 可选,bool,默认:false
    是否为将来使用保存卡。仅在创建支付时,而不是退款或重复交易时。

  • @return AbstractResponse - 所有可能的响应都在 Lumnn\SagePayPi\Transaction\Resopnse 命名空间中,并由 Lumnn\SagePayPi\Transaction\Response\ResponseFactory 创建

检索交易

GET /transactions/{transactionId}
Lumnn\SagePayPi\Transacton\Transactions::get(string $transactionId): AbstractResponse

创建 3D Secure 对象(3DSv1)

POST /transactions/{transactionId}/3d-secure
Lumnn\SagePayPi\Transacton\Transactions::create3DSv1(string $transactionId, string $paRes): string

返回状态字符串

创建 3D Secure 挑战(3DSv2)

POST /transactions/{transactionId}/3d-secure-challenge
Lumnn\SagePayPi\Transacton\Transactions::create3DSChallenge(string $transactionId, string $cRes): PaymentResponse

返回 PaymentResponse

创建指令

POST /transactions/{transactionId}/instructions
未实现

示例

构建客户端和使用资源

SagePayPi 类是一个基本客户端,能够执行对 API 的认证请求。

它还负责商户会话密钥和认证请求。

通常,除非您想直接与 API 通信,否则只需要实例化其他资源类。

use Lumnn\SagePayPi\SagePayPi;

$sagepay = new SagePayPi(
    'vendor',
    'integration_key',
    'integration_password',
    SagePayPi::TEST_ENDPOINT // or SagePayPi::LIVE_ENDPOINT, or ommit for live one
);

获取客户端后,您可以实例化资源类

use Lumnn\SagePayPi\Card\Cards;
use Lumnn\SagePayPi\Transaction\Transactions;

$cards = new Cards($sagepay);
$transactions = new Transactions($sagepay);

创建卡标识符

本例创建了一个信用卡表示,并将其POST到Opayo以获取卡标识。

此步骤可以在客户浏览器中完成(应该这样做),以避免直接处理信用卡详情。文档:https://developer-eu.elavon.com/docs/opayo/integrate-your-own-form#step-3

use Lumnn\SagePayPi\Card\CardDetails;
use Lumnn\SagePayPi\Card\Cards;

$cards = new Cards($sagepay);
$card = new CardDetails();
$card
    ->setCardNumber("1234123412341234")
    ->setCardholderName('Test Name')
    ->setExpiryDate('1223') // December 2023
    ->setSecurityCode('123');

$cardIdentifier = $cards->createIdentifier($card);

处理电话支付(无3D Secure)

use Lumnn\SagePayPi\Transaction\PaymentRequest;
use Lumnn\SagePayPi\Transaction\Transactions;

// $sagepay - from previous example
// $cardIdentifier - from previous examples
// $address - just intantiated and populated Address class. It's a simple getter setter class

$transactions = new Transactions($sagepay);

$paymentRequest = new PaymentRequest();
$paymentRequest
    ->setAmount(1000)
    ->setCurrency('GBP')
    ->setDescription('One testing service of SagePay Pi PHP Library')
    ->setBillingDetails($address)
    ->setCardIdentifier($cardIdentifier)
    ->setCustomerEmail('test@example.org')
    ->setEntryMethod(PaymentRequestInterface::ENTRY_TELEPHONE_ORDER)
    ->setTransactionType(PaymentRequestInterface::TYPE_PAYMENT)
    ->setVendorTxCode('php_lib_test'.time());

$payment = $this->transactions->createPayment($paymentRequest);

3D Secure支付

use Lumnn\SagePayPi\Transaction\PaymentRequest;
use Lumnn\SagePayPi\Transaction\Transactions;
use Lumnn\SagePayPi\Transaction\Request\StrongCustomerAuthentication;
use Lumnn\SagePayPi\Transaction\Request\StrongCustomerAuthenticationInterface;
use Lumnn\SagePayPi\Transaction\Response\ThreeDSv2AuthResponse;

// $sagepay - from previous example
// $cardIdentifier - from previous examples
// $address - just intantiated and populated Address class. It's a simple getter setter class

$transactions = new Transactions($sagepay);

$paymentRequest = new PaymentRequest();
$paymentRequest
    ->setAmount(1000)
    ->setCurrency('GBP')
    ->setDescription('One testing service of SagePay Pi PHP Library')
    ->setBillingDetails($address)
    ->setCardIdentifier($cardIdentifier)
    ->setCustomerEmail('test@example.org')
    ->setEntryMethod(PaymentRequestInterface::ENTRY_ECOMMERCE)
    ->setApply3DSecure(PaymentRequestInterface::SECURITY_CHECK_FORCE)
    ->setVendorTxCode('php_lib_test_3dv2'.time());

$strongCustomerAuth = new StrongCustomerAuthentication();

$notificationURL = 'http://127.0.0.1:8080';

$strongCustomerAuth
    ->setNotificationURL($notificationURL)
    ->setBrowserIP('127.0.0.1')
    ->setBrowserAcceptHeader('*/*')
    ->setBrowserJavascriptEnabled(true)
    ->setBrowserJavaEnabled(false)
    ->setBrowserLanguage('en-US')
    ->setBrowserColorDepth('32')
    ->setBrowserScreenHeight('1080')
    ->setBrowserScreenWidth('1920')
    ->setBrowserTZ('0')
    ->setBrowserUserAgent('Mozilla/5.0 (Linux x86_64; rv:93.0) Gecko/20100101 Firefox/93.0')
    ->setChallengeWindowSize('Small')
    ->setTransType(StrongCustomerAuthenticationInterface::TRANSACTION_TYPE_GOODS_AND_SERVICE_PURCHASE);

$paymentRequest->setStrongCustomerAuthentication($strongCustomerAuth);

$threeDSv2AuthResponse = $this->transactions->createPayment($paymentRequest);

// for simplicity in this example. However it's not guaranteed it's going to be 3Ds v2 challenge
if (!$payment instanceof ThreeDSv2AuthResponse) {
    throw new \Exception("Response invalid in this example");
}

$acsUrl = $threeDSv2AuthResponse->getAcsUrl();
$acsParams = [
    'creq' => $threeDSv2AuthResponse->getCReq(),
];

// at this point you should redirect customer to acsUrl with creq param
// it will then come back with cRes value. The cRes value will be POST-ed to
// your $notificationURL

$cRes = $_POST['cRes'];

$completedPayment = $transactions->create3DSChallenge($threeDSv2AuthResponse->getId(), $cRes);