На моем веб-сайте электронной коммерции я пытаюсь реализовать Amazon Pay. Здесь я успешно создал сеанс оформления заказа, но когда я выбираю оплату в Amazon, он возвращается на мой веб-сайт, но я хочу продолжить оплату в Amazon, а не возвращаться на свой веб-сайт. Я хочу, чтобы процесс был похож на кнопку экспресс-интеграции, которую Amazon предоставляет только для фиксированной оплаты. Я очень запутался и застрял в этом процессе. Пожалуйста, помогите мне решить эту проблему.
кнопка загрузки:
<div class = "col-md-12 col-sm-12 col-xs-12" style = "margin-top: 5%;">
<?php $this->load->view('widgets/payment/amazon_pay_payment'); ?>
</div>
amazon_pay.php
<div class = "row">
<div class = "col-md-12">
<div id = "amazonPayButtonContainer"></div>
<!-- Amazon Pay script start -->
<script src = "https://static-na.payments-amazon.com/checkout.js"></script>
<!-- <button id = "placeOrderButton" >Place Order</button>-->
<script>
console.info('Script loaded');
document.addEventListener("DOMContentLoaded", function () {
console.info('DOMContentLoaded event fired');
console.info('DOMContentLoaded event fired');
// Extract the amazonCheckoutSessionId from the URL
const urlParams = new URLSearchParams(window.location.search);
const amazonCheckoutSessionId = urlParams.get('amazonCheckoutSessionId');
console.info('Amazon Checkout Session ID:', amazonCheckoutSessionId);
const orderReferenceId = '<?php echo $custom; ?>';
<?php
$this->load->library('amazon_pay_lib');
// $checkoutSession = $this->amazon_pay_lib->createCheckoutSession(
// array(
// 'checkoutReviewReturnUrl' => g('base_url') . "checkout/notify",
// 'oid' => $order_id,
// 'code' => md5($order_id),
// 'payment_status' => 'Completed',
// 'custom' => $order_id
// ),
// array('storeId' => 'amzn1.application-oa2-client.XXXXXXXXXXXXXXXXXX')
// );
// $checkoutSession = $this->amazon_pay_lib->createCheckoutSession(
// array(
// 'checkoutReviewReturnUrl' => g('base_url') . "checkout/notify",
// 'oid' => $order_id,
// 'code' => md5($order_id),
// 'payment_status' => 'Completed',
// 'custom' => $order_id
// ),
// array('storeId' => 'amzn1.application-oa2-client.XXXXXXXXXXXXXXX')
// );
$checkoutSession = $this->amazon_pay_lib->createCheckoutSession(
array('checkoutReviewReturnUrl' => 'https://example.com/checkout/step3?oid=472',
'checkoutResultReturnUrl' => 'https://localhost/store/checkout_result'),
array('storeId' => 'amzn1.application-oa2-client.XXXXXXXXXXXXXXXXXXXX')
);
$payload = $checkoutSession['payload'];
$signature = $checkoutSession['signature'];
?>
console.info('Payload:', <?php echo json_encode($payload); ?>);
console.info('Signature:', <?php echo json_encode($signature); ?>);
const amazonPayButton = amazon.Pay.renderButton('#amazonPayButtonContainer', {
checkoutMode: 'Web/PuppetCheckout',
merchantId: 'XXXXXXXXXXXX',
publicKeyId: 'LIVE-XXXXXXXXXXXX',
ledgerCurrency: 'USD',
checkoutLanguage: 'en_US',
productType: 'PayOnly',
// sandbox: true,
placement: 'Cart',
buttonColor: 'Gold',
estimatedOrderAmount: {
"amount": '<?php echo json_encode($amount + $tax); ?>',
"currencyCode": "USD"
},
createCheckoutSessionConfig: {
storeId: 'amzn1.application-oa2-client.XXXXXXXXXXXX',
payloadJSON: '<?php echo $checkoutSession['payload']; ?>',
signature: '<?php echo $checkoutSession['signature']; ?>',
algorithm: 'AMZN-PAY-RSASSA-PSS-V2'
},
merchantMetadata: {
'merchantNote': 'Your merchant note',
'merchantReferenceId': '<?php echo $custom; ?>'
},
onError: function (error) {
console.info('onError callback:', error);
console.info('Error:', error.getErrorCode(), error.getErrorMessage());
},
authorization: function() {
loginOptions = {scope: " payments:widget", popup: true};
authRequest = amazon.Login.authorize (loginOptions, function(t) {
// console.info(t.access_token);
// console.info(t.expires_in);
console.info('checkout:', amazonCheckoutSessionId);
// showWalletWidget(null);
// fetch('<?php echo base_url('amazon_pay_lib/getShippingAndPaymentInfo'); ?>', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({
// checkoutSessionId: checkoutSessionId,
// }),
// })
// .then(response => response.json())
// .then(data => {
// console.info('Shipping and Payment Info:', data);
// })
// .catch(error => {
// console.error('Error fetching shipping and payment info:', error);
// });
});
}
// onAuthorize: function (authorizeResult) {
// console.info('onAuthorize callback:', authorizeResult);
// console.info('Authorization successful:', authorizeResult);
// const checkoutSessionId = authorizeResult.details.checkoutSessionId;
//// document.getElementById('placeOrderButton').disabled = false;
//
//// fetch('<?php echo base_url('amazon_pay_lib/getShippingAndPaymentInfo'); ?>', {
//// method: 'POST',
//// headers: {
//// 'Content-Type': 'application/json',
//// },
//// body: JSON.stringify({
//// checkoutSessionId: checkoutSessionId,
//// }),
//// })
//// .then(response => response.json())
//// .then(data => {
//// console.info('Shipping and Payment Info:', data);
//// })
//// .catch(error => {
//// console.error('Error fetching shipping and payment info:', error);
//// });
//
//
// }
});
});
</script>
<!-- Amazon Pay script end -->
</div>
</div>
Amazon_pay_lib.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
require_once FCPATH . 'vendor/autoload.php';
use Amazon\Pay\API\Client;
class Amazon_pay_lib {
private $client;
private $privateKeyPath; // Add this line
public function __construct() {
$this->privateKeyPath = FCPATH . 'AmazonPay_LIVE-XXXXXXXXXXXXXXX.pem';
$this->initializeAmazonPayClient();
}
private function initializeAmazonPayClient() {
$config = array(
'public_key_id' => 'LIVE-XXXXXXXXXXXXXX',
'private_key' => file_get_contents($this->privateKeyPath),
'region' => 'us',
// 'sandbox' => true,
'algorithm' => 'AMZN-PAY-RSASSA-PSS-V2',
);
try {
$this->client = new Client($config);
} catch (\Exception $e) {
die('Error initializing Amazon Pay client: ' . $e->getMessage());
}
}
public function getAccessToken() {
try {
$clientId = 'amzn1.application-oa2-client.XXXXXXXXXXXXXX';
$clientSecret = 'amzn1.oa2-cs.v1.XXXXXXXXXXXXXXXXXXXX'; // Replace with your client secret
$credentials = new \Amazon\Pay\API\Credentials($clientId, $clientSecret);
$payloadData = [
'grant_type' => 'client_credentials',
'scope' => 'payments:transactions_read',
];
$payload = new \Amazon\Pay\API\Request\AuthorizeFromCredentials($payloadData, $credentials);
$response = $this->client->getAccessToken($payload);
if ($response['status'] === 200) {
$data = json_decode($response['response'], true);
return $data['access_token'];
} else {
throw new \Exception('Error obtaining access token. Status: ' . $response['status']);
}
} catch (\Exception $e) {
throw $e;
}
}
public function updateCheckoutAndCompletePayment($checkoutSessionId) {
try {
// Update the checkout session (if needed)
// You can implement logic here to update the checkout session
// Complete the payment
$result = $this->client->completeCheckoutSession($checkoutSessionId);
if ($result['status'] === 200) {
// Payment completed successfully
return true;
} else {
// Payment completion failed
return false;
}
} catch (\Exception $e) {
// Handle exceptions
die('Error updating checkout session and completing payment: ' . $e->getMessage());
}
}
public function completePayment() {
try {
// Get the checkout session ID from the request
$checkoutSessionId = $_POST['checkoutSessionId'];
// Call the method to update checkout session and complete payment
$paymentCompleted = $this->updateCheckoutAndCompletePayment($checkoutSessionId);
if ($paymentCompleted) {
// Payment completed successfully
echo json_encode(['success' => true]);
} else {
// Payment completion failed
echo json_encode(['success' => false]);
}
} catch (\Exception $e) {
// Handle exceptions
echo json_encode(['error' => 'Error completing payment: ' . $e->getMessage()]);
}
}
// public function getShippingAndPaymentInfo($checkoutSessionId, $headers = array())
//{
// try {
// $result = $this->client->getCheckoutSession($checkoutSessionId, $headers);
//
// // ... (rest of the method remains the same)
// if ($result['status'] === 200) {
// $response = json_decode($result['response'], true);
// $checkoutSessionState = $response['statusDetails']['state'];
// $chargeId = $response['chargeId'];
// $chargePermissionId = $response['chargePermissionId'];
//
// // Handle other response data as needed
// $buyerName = $response['buyer']['name'];
// $buyerAddress = $response['buyer']['shippingAddress'];
//
// // Return the shipping and payment info
// return array(
// 'checkoutSessionState' => $checkoutSessionState,
// 'chargeId' => $chargeId,
// 'chargePermissionId' => $chargePermissionId,
// 'buyerName' => $buyerName,
// 'buyerAddress' => $buyerAddress,
// // Add other data as needed
// );
// } else {
// // Handle the error
// return array(
// 'error' => 'Error fetching shipping and payment info. Status: ' . $result['status'],
// );
// }
// } catch (\Exception $e) {
// // Handle the exception
// return array(
// 'error' => 'Exception: ' . $e->getMessage(),
// );
// }
//}
public function getShippingAndPaymentInfo($checkoutSessionId) {
try {
$result = $this->client->getCheckoutSession($checkoutSessionId);
if ($result['status'] === 200) {
$response = json_decode($result['response'], true);
$checkoutSessionState = $response['statusDetails']['state'];
$chargeId = $response['chargeId'];
$chargePermissionId = $response['chargePermissionId'];
// Handle other response data as needed
$buyerName = $response['buyer']['name'];
$buyerAddress = $response['buyer']['shippingAddress'];
// Return the shipping and payment info
return array(
'checkoutSessionState' => $checkoutSessionState,
'chargeId' => $chargeId,
'chargePermissionId' => $chargePermissionId,
'buyerName' => $buyerName,
'buyerAddress' => $buyerAddress,
// Add other data as needed
);
} else {
// Handle the error
return array(
'error' => 'Error fetching shipping and payment info. Status: ' . $result['status'],
);
}
} catch (\Exception $e) {
// Handle the exception
return array(
'error' => 'Exception: ' . $e->getMessage(),
);
}
}
public function generateAmazonPaySignature($payload) {
try {
return $this->client->generateButtonSignature($payload);
echo $signature . "\n";
} catch (\Exception $e) {
die('Error generating Amazon Pay signature: ' . $e->getMessage());
}
}
public function createCheckoutSession($payload, $headers = array()) {
try {
// echo 'Request Payload: ' . json_encode($payload) . '<br>';
// Echo the headers data for debugging
// echo 'Request Headers: ' . json_encode($headers) . '<br>';
// Log the payload data before making the request
// file_put_contents(FCPATH . 'file.log', 'Request Payload: ' . json_encode($payload) . PHP_EOL, FILE_APPEND);
// Log the headers data before making the request
// file_put_contents(FCPATH . 'file.log', 'Request Headers: ' . json_encode($headers) . PHP_EOL, FILE_APPEND);
$amazonpay_config = array(
'public_key_id' => 'LIVE-XXXXXXXXXXXXX',
'private_key' => file_get_contents($this->privateKeyPath),
'region' => 'us',
// 'sandbox' => true,
'algorithm' => 'AMZN-PAY-RSASSA-PSS-V2'
);
$client = new \Amazon\Pay\API\Client($amazonpay_config);
$headers = array('x-amz-pay-idempotency-key' => uniqid());
$checkoutSession = $client->createCheckoutSession($payload, $headers);
$payload = json_encode([
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXXXXXXXXXXXX',
'webCheckoutDetails' => [
'checkoutReviewReturnUrl' => $payload['checkoutReviewReturnUrl'],
],
]);
$signature = $client->generateButtonSignature($payload);
// Debug statements
file_put_contents(FCPATH . 'file.log', 'Payload: ' . $payload . PHP_EOL, FILE_APPEND);
file_put_contents(FCPATH . 'file.log', 'Signature: ' . $signature . PHP_EOL, FILE_APPEND);
return [
'payload' => $payload,
'signature' => $signature,
];
// Check if the 'x-amz-pay-authtoken' key exists in the headers
// if (isset($checkoutSession['headers']['x-amz-pay-authtoken'])) {
// // Obtain the auth token from the response headers
// $authToken = $checkoutSession['headers']['x-amz-pay-authtoken'];
//
// // Include the auth token in the headers for subsequent requests
// $headers['x-amz-pay-authtoken'] = $authToken;
// } else {
// // Handle the case where the key is not set (perhaps log a warning)
// // $headers['x-amz-pay-authtoken'] will remain unset in this case
// }
$responsePayload = $checkoutSession['payload'];
$responseSignature = $checkoutSession['signature'];
// return [
// 'payload' => $responsePayload,
// 'signature' => $responseSignature,
// ];
// return $checkoutSession;
} catch (\Exception $e) {
echo 'Error creating checkout session: ' . $e->getMessage() . '<br>';
file_put_contents(FCPATH . 'file.log', 'Error creating checkout session: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
die('Error creating checkout session: ' . $e->getMessage());
} catch (\ValueError $ve) {
file_put_contents(FCPATH . 'file.log', 'Error: ' . $ve->getMessage() . PHP_EOL, FILE_APPEND);
echo 'Error: ' . $ve->getMessage() . '<br>';
die('Error: ' . $ve->getMessage());
}
}
public function updateCheckoutAndCompleteAmazonPayment($checkoutSessionId) {
try {
$result = $this->client->completeCheckoutSession($checkoutSessionId);
if ($result['status'] === 200) {
return true;
} else {
return false;
}
} catch (\Exception $e) {
die('Error updating checkout session and completing payment: ' . $e->getMessage());
}
}
public function updateCheckoutSession() {
try {
// Get the checkout session ID and updated payload from the request
$checkoutSessionId = $_POST['checkoutSessionId'];
$updatedPayload = json_decode($_POST['updatedPayload'], true);
$amazonpay_config = array(
'public_key_id' => 'LIVE-XXXXXXXXXXXXXXXXXX',
'private_key' => file_get_contents($this->privateKeyPath),
'region' => 'us',
'algorithm' => 'AMZN-PAY-RSASSA-PSS-V2'
);
$client = new \Amazon\Pay\API\Client($amazonpay_config);
// Update the checkout session with the new payload
$result = $client->updateCheckoutSession($checkoutSessionId, $updatedPayload);
if ($result['status'] === 200) {
// Checkout session updated successfully
$response = json_decode($result['response'], true);
echo json_encode(['success' => true, 'response' => $response]);
} else {
// Checkout session update failed
echo json_encode(['success' => false, 'error' => $result['response']]);
}
} catch (\Exception $e) {
// Handle exceptions
echo json_encode(['error' => 'Error updating checkout session: ' . $e->getMessage()]);
}
}
}
?>
Я успешно сгенерировал сеанс оформления заказа, но не знаю, как продолжить оплату. Я не хочу возвращаться на свой веб-сайт и продолжать работу снова, вместо этого, как только будет выбран способ оплаты, он должен перейти на саму Amazon и произвести оплату.






Чтобы осуществить прямую проверку без перенаправления обратно на исходный сайт до завершения оплаты, вам нужно установить для параметра webCheckoutDetails.checkoutMode сеанса CheckoutSession значение ProcessOrder.
Обратите внимание, что в этом случае вам также необходимо отправить addressDetails, если только вы не находитесь в режиме PayOnly.
Также вам следует оставить checkoutReviewReturnUrl пустым.
Для справки: https://developer.amazon.com/de/docs/amazon-pay-api-v2/checkout-session.html