我正在创建一个自定义支付网关 - 有两个选项:
第一个效果很好。
在第二个中,如果没有 OTP,它看起来工作正常。
public function process_payment( $order_id ) {
$result = $this->request->result( $order );
// Redirect URL and success response exists.
if ( isset( $result->response->Data->paymentPage->paymentPageURL ) && in_array( $result->response->ApiResponse->ResponseCode, array( 'PC-B050000', 'PC-B050001', 'PC-B050002' ) ) ) {
// Assuming success.
return array(
'result' => 'success',
'redirect' => $result->response->Data->paymentPage->paymentPageURL,
);
// No redirect URL, but success.
} elseif ( in_array( $result->response->ApiResponse->ResponseCode, array( 'PC-B050000', 'PC-B050001', 'PC-B050002' ) ) ) {
// Success but pending, requires account verification like OTP.
if ( isset( $result->response->Data->paymentIncompleteResult->aresACSChallenge->transStatus ) && 'C' === $result->response->Data->paymentIncompleteResult->aresACSChallenge->transStatus ) {
// Handle OTP verification etc.
wc_add_notice( 'ERROR: ' . esc_html( $result->response->ApiResponse->MarketingDescription ), 'error' );
return;
}
wc_add_notice( 'SUCCESS: ' . esc_html( $result->response->ApiResponse->MarketingDescription ), 'success' );
return;
} elseif ( isset( $result->response->ApiResponse->MarketingDescription ) ) {
wc_add_notice( 'ERROR: ' . esc_html( $result->response->ApiResponse->MarketingDescription ), 'error' );
// Failed with error.
return;
}
}
如何处理 OTP 验证?它给出的响应如下:
[05-Apr-2024 09:03:58 UTC] stdClass Object
(
[response] => stdClass Object
(
[Data] => stdClass Object
(
[paymentIncompleteResult] => stdClass Object
(
[notificationURLs] =>
[aresACSChallenge] => stdClass Object
(
[transStatus] => C
[acsURL] => https://paysecure.nicasiabank.com/3dsAcs2FrontOfficeWeb/paymentAuthentication
[CReq] => PGh0bWw-PGhlYWQ-PC9oZWFkPjxib2R5Pgo8Zm9ybSBuYW1lPSdjcmVxRm9ybScgbWV0aG9kPSdQT1NUJyBhY3Rpb249J2h0dHBzOi8vcGF5c2VjdXJlLm5pY2FzaWFiYW5rLmNvbS8zZHNBY3MyRnJvbnRPZmZpY2VXZWIvcGF5bWVudEF1dGhlbnRpY2F0aW9uJz4KICAgIDxpbnB1dCB0eXBlPSdoaWRkZW4nIG5hbWU9J2NyZXEnIHZhbHVlPSdleUp0WlhOellXZGxWSGx3WlNJNklrTlNaWEVpTENKamFHRnNiR1Z1WjJWWGFXNWtiM2RUYVhwbElqb2lNRE1pTENKMGFISmxaVVJUVTJWeWRtVnlWSEpoYm5OSlJDSTZJbUZoTVdWbE5HUm1MVFprT0RZdE5Ea3lZUzA0WVdVNUxUWXdPV05rWkRjelltTXlPQ0lzSW1GamMxUnlZVzV6U1VRaU9pSTBOelF5WWpBM1lTMW1NekppTFRFeFpXVXRPV1V4WXkweE0yVXhaREppWm1Fd09USWlMQ0p0WlhOellXZGxWbVZ5YzJsdmJpSTZJakl1TWk0d0luMCc-CiAgICA8aW5wdXQgdHlwZT0naGlkZGVuJyBuYW1lPSd0aHJlZURTU2Vzc2lvbkRhdGEnIHZhbHVlPSdZV0V4WldVMFpHWXRObVE0TmkwME9USmhMVGhoWlRrdE5qQTVZMlJrTnpOaVl6STQnPgogICAgPG5vc2NyaXB0PjxidXR0b24-UGxlYXNlIGNsaWNrIGhlcmUgdG8gY29udGludWU8L2J1dHRvbj48L25vc2NyaXB0Pgo8L2Zvcm0-CiAgICA8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc-ZG9jdW1lbnQuY3JlcUZvcm0uc3VibWl0KCk7PC9zY3JpcHQ-PC9ib2R5PjwvaHRtbD4
[rawCreq] => eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJjaGFsbGVuZ2VXaW5kb3dTaXplIjoiMDMiLCJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImFhMWVlNGRmLTZkODYtNDkyYS04YWU5LTYwOWNkZDczYmMyOCIsImFjc1RyYW5zSUQiOiI0NzQyYjA3YS1mMzJiLTExZWUtOWUxYy0xM2UxZDJiZmEwOTIiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMi4wIn0
[ChallengeHtml] => PGh0bWw-PGhlYWQ-PC9oZWFkPjxib2R5Pgo8Zm9ybSBuYW1lPSdjcmVxRm9ybScgbWV0aG9kPSdQT1NUJyBhY3Rpb249J2h0dHBzOi8vcGF5c2VjdXJlLm5pY2FzaWFiYW5rLmNvbS8zZHNBY3MyRnJvbnRPZmZpY2VXZWIvcGF5bWVudEF1dGhlbnRpY2F0aW9uJz4KICAgIDxpbnB1dCB0eXBlPSdoaWRkZW4nIG5hbWU9J2NyZXEnIHZhbHVlPSdleUp0WlhOellXZGxWSGx3WlNJNklrTlNaWEVpTENKamFHRnNiR1Z1WjJWWGFXNWtiM2RUYVhwbElqb2lNRE1pTENKMGFISmxaVVJUVTJWeWRtVnlWSEpoYm5OSlJDSTZJbUZoTVdWbE5HUm1MVFprT0RZdE5Ea3lZUzA0WVdVNUxUWXdPV05rWkRjelltTXlPQ0lzSW1GamMxUnlZVzV6U1VRaU9pSTBOelF5WWpBM1lTMW1NekppTFRFeFpXVXRPV1V4WXkweE0yVXhaREppWm1Fd09USWlMQ0p0WlhOellXZGxWbVZ5YzJsdmJpSTZJakl1TWk0d0luMCc-CiAgICA8aW5wdXQgdHlwZT0naGlkZGVuJyBuYW1lPSd0aHJlZURTU2Vzc2lvbkRhdGEnIHZhbHVlPSdZV0V4WldVMFpHWXRObVE0TmkwME9USmhMVGhoWlRrdE5qQTVZMlJrTnpOaVl6STQnPgogICAgPG5vc2NyaXB0PjxidXR0b24-UGxlYXNlIGNsaWNrIGhlcmUgdG8gY29udGludWU8L2J1dHRvbj48L25vc2NyaXB0Pgo8L2Zvcm0-CiAgICA8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc-ZG9jdW1lbnQuY3JlcUZvcm0uc3VibWl0KCk7PC9zY3JpcHQ-PC9ib2R5PjwvaHRtbD4
[threeDSSessionData] => YWExZWU0ZGYtNmQ4Ni00OTJhLThhZTktNjA5Y2RkNzNiYzI4
)
[failedReason] =>
[availablePaymentTypes] =>
[untokenizedStoredCardList] =>
[storedCardUniqueID] =>
[paymentExpiryDateTime] => 2024-04-05T09:48:40.0051453Z
[merchantIdForMcp] =>
[mcpDetails] =>
[preferredPaymentTypes] => Array
(
[0] => CC
)
[transactionDateTime] => 2024-04-05T09:03:42.987867Z
[orderNo] => 297
[productDescription] => Another Product - 3
[InvoiceNo2C2P] => HBL0000000047
[pspReferenceNo] =>
[controllerInternalID] => e40bc631b7a447afb42574998de7b380
[paymentStatusInfo] => stdClass Object
(
[PaymentStatus] => I
[PaymentStep] => AC
[LastUpdatedDateTime] => 2024-04-05T09:03:39.9619103Z
)
[paymentType] => CC
[channelCode] =>
[agentCode] =>
[mcpFlag] => N
[transactionAmount] => stdClass Object
(
[AmountText] => 000000000003
[CurrencyCode] => USD
[DecimalPlaces] => 2
[Amount] => 0.03
)
[settlementAmount] => stdClass Object
(
[AmountText] => 000000000003
[CurrencyCode] => USD
[DecimalPlaces] => 2
[Amount] => 0.03
)
[customFieldList] =>
[clientIp] =>
[officeId] => 9104135843
[ddcId] =>
)
[paymentPage] =>
)
[Version] => 1.0
[ApiResponse] => stdClass Object
(
[ResponseMessageId] => 03dad34c-ae08-4636-9e0c-ff777504d864
[ResponseToRequestMessageId] => 866900bf-d915-3415-4844-039c43152970
[ResponseCode] => PC-B050001
[ResponseDescription] => Success
[ResponseDateTime] => 2024-04-05T09:03:42.9878657Z
[ResponseTime] => 3100
[AcquirerResponseCode] =>
[AcquirerResponseDescription] =>
[EciValue] =>
[MarketingDescription] => Payment success but not completed yet.
Please finish your payment via selected payment channel later.
)
)
[aud] => 4b0d276fcaf04fbd9469859949b1b83c
[iss] => PacoIssuer
[exp] => 1712311423
[iat] => 1712307823
[nbf] => 1712307823
)
// Handle OTP verification etc.
if (isset($result->response->Data->paymentIncompleteResult->aresACSChallenge->transStatus) && $result->response->Data->paymentIncompleteResult->aresACSChallenge->transStatus === 'C') {
// OTP verification is required.
// Redirect the customer to the ACS URL for OTP verification.
$acsUrl = $result->response->Data->paymentIncompleteResult->aresACSChallenge->acsURL;
$cReq = $result->response->Data->paymentIncompleteResult->aresACSChallenge->CReq;
// You can store necessary data like order ID, session, etc., in session variables or database to retrieve them later.
// For example:
$_SESSION['order_id'] = $order_id;
$_SESSION['acs_url'] = $acsUrl;
$_SESSION['c_req'] = $cReq;
// Redirect the customer to the ACS URL.
wp_redirect($acsUrl);
exit;
} else {
// Handle other cases like success, failure, etc.
if (isset($result->response->ApiResponse->MarketingDescription)) {
wc_add_notice('ERROR: ' . esc_html($result->response->ApiResponse->MarketingDescription), 'error');
} else {
wc_add_notice('SUCCESS: Payment processed successfully.', 'success');
}
}