lumnn / sagepay-pi
Opayo PI(之前称为 SagePay PI)PHP API,使用 PSR7、PSR17、PSR18 标准。
Requires
- php: >=7.4
- php-http/discovery: ^1.14
- psr/http-client: ^1.0
- psr/http-client-implementation: ^1.0
- psr/http-factory-implementation: ^1.0
- psr/http-message: ^1.0
- psr/http-message-implementation: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.2
- guzzlehttp/guzzle: ^7.4
- guzzlehttp/psr7: ^2.1
- php-http/curl-client: ^2.2
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.11
README
Opayo PI(之前称为 Sagepay PI)支付 API 的 PHP 客户端。
安装
composer require lumnn/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);