add_action( 'woocommerce_init', function() {
// Payment Gateway Class
class WC_Gateway_QualPayCheckout extends WC_Payment_Gateway {
// Constructor
function __construct() {
$this->endpoint = 'https://api.qualpay.com';
$this->has_fields = false;
$this->id = 'qualpaycheckout';
$this->method_title = 'QualPay Checkout';
$this->method_description = 'Implements QualPay Checkout Pay Page';
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
add_action(
'woocommerce_update_options_payment_gateways_' . $this->id,
[ $this, 'process_admin_options' ]
);
}
// Settings Fields
function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => 'Enable QualPay Checkout',
'default' => 'yes',
),
'testmode' => array(
'title' => __( 'Test mode', 'woocommerce' ),
'type' => 'checkbox',
'label' => 'Enable test mode',
'default' => 'yes',
),
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
),
'api_key' => array(
'title' => 'QualPay API Key',
'type' => 'text',
),
'checkout_id' => array(
'title' => 'QualPay Checkout ID',
'type' => 'number',
),
'currency_code' => array(
'title' => 'QualPay Currency Code',
'type' => 'number',
),
'profile_id' => array(
'title' => 'QualPay Profile ID',
'type' => 'number',
),
);
}
// WooCommerce Order Submitted
function process_payment( $order_id ) {
// Get Customer And Order
$customer = WC()->session->get( 'customer' );
$order = new WC_Order( $order_id );
// Set Payent Pending Status
$order->update_status( 'pending', __( 'Awaiting payment', 'woocommerce' ) );
// Build Checkout Request
$request = ( object ) [
'amt_tran' => ( float ) $order->get_total(),
'tran_currency' => ( string ) $this->settings['currency_code'],
'purchase_id' => 'WC-' . $order_id,
'profile_id' => ( string ) $this->settings['profile_id'],
'merch_ref_num' => 'WC-' . $order_id,
'customer_first_name' => $customer['first_name'],
'customer_last_name' => $customer['last_name'],
'customer_firm_name' => $customer['company'],
'customer_email' => $customer['email'],
'billing_addr1' => $customer['address_1'],
'billing_addr2' => $customer['address_2'],
'billing_state' => $customer['state'],
'billing_city' => $customer['city'],
'billing_zip' => $customer['postcode'],
'moto_ecomm_ind' => '7',
'preferences' => ( object ) [
'success_url' => $this->get_return_url( $order ),
'failure_url' => $order->get_checkout_payment_url(),
'allow_partial_payments' => false,
'allow_save_card' => false,
'allow_ach_payment' => false,
'email_receipt' => false,
'request_type' => 'sale',
'expire_in_secs' => 10000,
],
'checkout_profile_id' => $this->settings['checkout_id'],
];
$args = [
'headers' => [
'Authorization:Basic' => base64_encode( $this->settings['api_key'] . ':' ),
'Content-Type' => 'application/json; charset=utf-8',
],
'data_format' => 'body',
'body' => json_encode( $request )
];
// Send Checkout Request
if( $this->settings['testmode'] == 'yes' ) {
$this->endpoint = str_replace( 'api', 'api-test', $this->endpoint );
}
$url = $this->endpoint . '/platform/checkout';
$response = wp_remote_post( $url, $args );
// Parse Response
$response = isset( $response['body'] ) ? json_decode( $response['body'] ) : $response;
$message = isset( $response->message ) ? $response->message : $response;
$data = isset( $response->data ) ? $response->data : '';
$checkout_link = isset( $data->checkout_link ) ? $data->checkout_link : '';
$checkout_id = isset( $data->checkout_id ) ? $data->checkout_id : '';
// Handle Checkout Error
if( ! $checkout_link ) {
$message = sprintf(
'Problem with QualPay Checkout: %s',
print_r( $message, true )
);
$order->update_status( 'failed', $message );
wc_add_notice( print_r( $message, true ), 'error' );
return;
}
// Handle Checkout Success
$order->add_order_note( 'Redirected to QP Checkout ID ' . $checkout_id );
return [ 'result' => 'success', 'redirect' => $checkout_link ];
}
}
} );
// Add Gateway To WooCommerce
add_filter( 'woocommerce_payment_gateways', function( $methods ) {
$methods[] = 'WC_Gateway_QualPayCheckout';
return $methods;
} );
// Handle Double Querystring Bug
add_action( 'template_redirect', function() {
$order_key = isset( $_GET['key'] ) ? esc_attr( $_GET['key'] ) : '';
$rcode = isset( $_GET['rcode'] ) ? esc_attr( $_GET['rcode'] ) : '';
if( strchr( $order_key, '?' ) ) {
global $wp;
$order_id = absint( $wp->query_vars['order-received'] );
if( ! $order_id ) {
$order_id = absint( $wp->query_vars['order-pay'] );
}
if( ! $order_id ) { return; }
$order = new WC_Order( $order_id );
if( is_wp_error( $order ) || ! $order ) { return; }
$order_key = substr( $order_key, 0, strpos( $order_key, '?' ) );
$redirect = empty( $_GET['pay_for_order'] )
? $order->get_checkout_order_received_url() . '&rcode=' . $rcode
: $order->get_checkout_payment_url() . '&rcode=' . $rcode;
exit( wp_redirect( $redirect ) );
}
} );
// Handle Payment Errors
add_action( 'template_redirect', function() {
$rcode = isset( $_GET['rcode'] ) ? esc_attr( $_GET['rcode'] ) : '';
if( $rcode == '000' || ! $rcode ) { return; }
$rcodes = [
'000' => 'Success',
'005' => 'Simulation',
100 => 'Bad request',
101 => 'Invalid credentials',
102 => 'Invalid pg_id',
103 => 'Missing cardholder data',
104 => 'Invalid transaction amount',
105 => 'Missing auth_code',
106 => 'Invalid AVS (Address Verification Service) data',
107 => 'Invalid expiration date',
108 => 'Invalid card number',
109 => 'Field length validation failed',
110 => 'Dynamic DBA not allowed',
111 => 'Credits not allowed',
112 => 'Invalid customer data',
113 => 'Declined due to merchant risk settings',
114 => 'Invalid currency code',
115 => 'Invalid surcharge data',
116 => 'Invalid email address',
117 => 'Email address is required',
118 => 'Invalid merchant logo URL',
119 => 'Invalid ACH payment',
401 => 'Void failed',
402 => 'Refund failed',
403 => 'Capture failed',
404 => 'Batch close failed',
405 => 'Tokenization failed',
998 => 'Timeout',
999 => 'Internal error',
];
if( empty( $rcodes[$rcode] ) ) {
$rcodes[$rcode] = 'Missing error descriptor';
}
$error_message = sprintf(
'QualPay Checkout error code %s: %s', $rcode, $rcodes[$rcode]
);
// Set Woo Order Status And Note
$order_id = get_query_var( 'order-pay' );
if( intval( $order_id ) ) {
$order = new WC_Order( $order_id );
if( ! is_wp_error( $order ) && $order ) {
$order->update_status( 'failed' );
$order->add_order_note( $error_message );
}
}
// Set Woo Notice
if( function_exists( 'wc_add_notice' ) ) {
$message = sprintf(
'
Please try again.
<a href="mailto:%s">Let us know if the problem persists.</a>
',
get_bloginfo( 'admin_email' )
);
wc_add_notice( $error_message . $message, 'error' );
}
} );
// Handle Successful Payments
add_action( 'woocommerce_thankyou_qualpaycheckout', function( $order_id ) {
// Get Order
$order = new WC_Order( $order_id );
if( is_wp_error( $order ) || ! $order ) { return; }
// Security Check
$order_key = isset( $_GET['key'] ) ? esc_attr( $_GET['key'] ) : '';
if( $order_key != $order->get_order_key() ) { return; }
// Return Code Check
$rcode = isset( $_GET['rcode'] ) ? esc_attr( $_GET['rcode'] ) : '';
if( $rcode != '000' ) { return; }
// Empty The Cart
global $woocommerce;
$woocommerce->cart->empty_cart();
// Set Order Note
$order->add_order_note( 'QualPay Checkout payment success.' );
// Mark Order Paid
$order->payment_complete();
} );
QualPay Checkout payment gateway
Implements a payment gateway for QualPay Checkout (secure order payment page) for WooCommerce. Works in both checkout place-order flow and my account order-pay flow.
Must be set to run on both front-end and back-end (everywhere).
How to use
- Log into a staging, development, or locally hosted clone of your site
- Install and activate Code Snippets
- WP Admin > Snippets > Add New
- Copy and paste the code from the Description tab above
- Check to ensure formatting came over properly and no syntax errors show up in the editor
- Customize the code as desired
- Add a meaningful title
- Select whether to run on front-end or back-end (or both)
- Click “Save and Activate”
- Test your site to ensure it works
- Disable if any problems, or recover
- Repeat for live environment
License
All code snippets are licensed GPLv2 (or later) matching WordPress licensing.
Disclaimer of warranty:
Except when otherwise stated in writing the copyright holders and/or other parties provide the program as-is without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose.
Support
- Describe the issue and what you’ve observed.
- Describe your expected outcome(s).
- List steps to reproduce the issue.
- Optionally provide screen-shot or video URLs.
- Email to [email protected]
