dhavalsagepaypi / sagepay-pi
Opayo PI(原名 SagePay PI)PHP API,使用 PSR7、PSR17、PSR18 标准。
Requires
- php: >=7.2
- 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
SagePayPi (Opayo)
受以下项目启发 sagepay-pi
更新
错误响应中存在问题的解决。
Opayo PI PHP 客户端
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);