购物车含两件商品时SagePay报3021格式错误问题求助
Alright, let's break down why you're hitting Error 3021 (Format Error) when adding two items to your cart, while single-item transactions work perfectly with SagePay. This almost always boils down to missing required multi-item formatting that the gateway expects—something your current code isn't handling.
The Root Issue in Your Code
Your existing code only sets the total order amount ($item_total) but doesn't provide individual item details to SagePay. For single items, the gateway often tolerates this simplified approach, but when you have multiple items, it needs explicit data for each product to validate the transaction structure. Without that, it throws a format error.
Fix Steps & Modified Code
Here's how to adjust your code to support multi-item transactions properly:
- Add Individual Item Entries: Use your SagePay library's
addItem()method (standard in most SagePay SDKs) to pass details for each cart item. - Validate Total Calculation: Ensure the total amount is the exact sum of all item totals, formatted correctly (two decimal places for GBP).
- Check for Invalid Characters: Make sure item names/descriptions don't contain special characters that break the gateway's request format.
require_once ('SagePay/lib/SagePay.php'); $sagePay = new SagePay(); $sagePay->setCurrency('GBP'); // Assume $cart_items is your array of cart products (each with name, price, quantity) $item_total = 0; foreach ($cart_items as $item) { // Calculate individual item total with proper decimal formatting $individual_item_total = number_format($item['price'] * $item['quantity'], 2); // Add each item to the SagePay request $sagePay->addItem( $item['name'], // Item name $item['price'], // Unit price (formatted to 2 decimals) $item['quantity'], // Quantity (positive integer) $individual_item_total // Total for this item ); $item_total += $individual_item_total; } // Set the total order amount (ensure it's formatted to 2 decimals) $sagePay->setAmount(number_format($item_total, 2)); $sagePay->setDescription("Bates Environmental Ltd"); $sagePay->setBillingSurname($user['Surname']); $sagePay->setBillingFirstnames($user['FirstName']); $sagePay->setBillingCity($user['BillingAddressCity']); $sagePay->setBillingPostCode($user['BillingAddressPostCode']); $sagePay->setBillingAddress1($user['BillingAddressLine1']); $sagePay->setBillingCountry('GB'); $sagePay->setDeliverySameAsBilling();
Additional Troubleshooting Tips
- Enable SagePay Debug Logs: Check the full request payload being sent to SagePay when you have two items. Compare it to the single-item request—this will highlight exactly which field is causing the format mismatch.
- Verify Library Version: Ensure your SagePay library is up-to-date. Older versions might have bugs or missing support for multi-item validation rules.
- Double-Check Numeric Formats: All prices and totals must be in valid decimal format (e.g.,
10.00instead of10or10,00for GBP).
内容的提问来源于stack exchange,提问作者Mohammed Alh

