SagePay
The Phone Orders for WooCommerce plugin works with the SagePay Direct payment gateway. When you create a phone order and then click the Pay order as the customer button (or redirect the customer to the payment page), SagePay may still try to perform a 3D‑Secure check. For manual orders placed over the phone, you often want to bypass this extra step and authorise the transaction immediately. The code below disables 3D‑Secure checks for any phone order that uses the SagePay Direct gateway and forces it to always authorise.
Prerequisite: This feature requires the Pro version of Phone Orders for WooCommerce.
The Complete Code Snippet
|
1 2 3 4 5 6 7 8 9 10 11 |
add_action( 'woocommerce_before_pay_action', function( $order ){ $user_id = get_post_meta( $order->get_id() , '_wpo_order_creator', true); // created using Phone Orders plugin? if($user_id AND $_POST['payment_method'] == "sagepaydirect" ){ add_filter( 'http_request_args', function($data, $url ){ parse_str($data["body"], $vars); $vars["Apply3DSecure"] = 2; // Do not perform 3D-Secure checks for this transaction and always authorise. $data["body"] = http_build_query( $vars ); return $data; },10,2); } }); |
How the Code Works
The snippet attaches a function to the woocommerce_before_pay_action hook, which runs just before the customer (or agent) is redirected to the payment page.
| Element | Explanation |
|---|---|
add_action( 'woocommerce_before_pay_action', ... ) | Fires when the “Pay” action is triggered for an order. |
$order | The WC_Order object for which payment is being processed. |
$user_id = get_post_meta( $order->get_id(), '_wpo_order_creator', true ); | Retrieves the ID of the user who created the order. This meta key is set automatically when a phone order is created. |
if ( $user_id && $_POST['payment_method'] == "sagepaydirect" ) | Confirms that the order was created by Phone Orders and that the selected payment method is SagePay Direct. |
add_filter( 'http_request_args', ... ) | Intercepts the HTTP request that the SagePay gateway sends to its server. |
parse_str( $data["body"], $vars ); | Converts the request body string into an associative array. |
$vars["Apply3DSecure"] = 2; | Overrides the 3D‑Secure parameter. Value 2 tells SagePay to skip 3D‑Secure checks and authorise the transaction immediately. |
$data["body"] = http_build_query( $vars ); | Rebuilds the request body with the modified parameter. |
return $data; | Returns the modified HTTP request arguments to the gateway. |
Important: The value
2means “Do not perform 3D‑Secure checks for this transaction and always authorise”. Do not change this value unless you have a specific reason.
Step‑by‑Step Implementation
Step 1: Verify the payment gateway ID
The code assumes the SagePay Direct gateway has the ID sagepaydirect. If your site uses a different ID (e.g., sagepay, sagepay_direct), replace "sagepaydirect" with the correct string.
How to find the gateway ID:
- Go to WooCommerce → Settings → Payments.
- Find the SagePay gateway and click its Manage button.
- Look at the URL in your browser; it contains a parameter
section=. For example,section=wc_gateway_sagepaydirectindicates the ID issagepaydirect.
Step 2: Add the PHP snippet
- Option A (Recommended): Use the free Code Snippets plugin. Install it from Plugins → Add Newby searching for “Code Snippets”.
- Option B: Add the code to your child theme’s
functions.phpfile. Navigate to Appearance → Theme File Editor, openfunctions.php, paste the code at the bottom, and save.
Step 3: Test the integration
- Create a new phone order.
- During order creation, select SagePay Direct as the payment method.
- Complete the order (status becomes “Pending payment”).
- Click the Pay order as the customer button (Pro feature) or send the customer to the payment page.
- Complete the payment process.
The transaction should now process without prompting for 3D‑Secure. Check the order status – it should change to “Processing” or “Completed” immediately after payment.