Changeset 2976105
- Timestamp:
- 10/08/2023 07:03:02 PM (2 years ago)
- Location:
- credo-payment-forms/trunk
- Files:
-
- 2 added
- 3 edited
-
assets/js/credo.js (added)
-
assets/js/credo.min.js (added)
-
includes/class-wc-gateway-credo.php (modified) (2 diffs)
-
readme.txt (modified) (3 diffs)
-
woo-credo.php (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
credo-payment-forms/trunk/includes/class-wc-gateway-credo.php
r2969965 r2976105 2 2 3 3 if ( ! defined( 'ABSPATH' ) ) { 4 exit;4 exit; 5 5 } 6 6 7 7 class WC_Gateway_Credo extends WC_Payment_Gateway_CC { 8 8 9 /** 10 * Is test mode active? 11 * 12 * @var bool 13 */ 14 public $testmode; 15 16 /** 17 * Should orders be marked as complete after payment? 18 * 19 * @var bool 20 */ 21 public $autocomplete_order; 22 23 /** 24 * Credo payment page type. 25 * 26 * @var string 27 */ 28 public $payment_page; 29 30 /** 31 * Credo test public key. 32 * 33 * @var string 34 */ 35 public $test_public_key; 36 37 /** 38 * Credo test secret key. 39 * 40 * @var string 41 */ 42 public $test_secret_key; 43 44 /** 45 * Credo live public key. 46 * 47 * @var string 48 */ 49 public $live_public_key; 50 51 /** 52 * Credo live secret key. 53 * 54 * @var string 55 */ 56 public $live_secret_key; 57 58 /** 59 * Should we save customer cards? 60 * 61 * @var bool 62 */ 63 public $saved_cards; 64 65 /** 66 * Should Credo split payment be enabled. 67 * 68 * @var bool 69 */ 70 public $split_payment; 71 72 /** 73 * Should the cancel & remove order button be removed on the pay for order page. 74 * 75 * @var bool 76 */ 77 public $remove_cancel_order_button; 78 79 /** 80 * Credo sub account code. 81 * 82 * @var string 83 */ 84 public $service_code; 85 86 /** 87 * Who bears Credo charges? 88 * 89 * @var string 90 */ 91 public $charges_bearer; 92 93 /** 94 * A flat fee to charge the sub account for each transaction. 95 * 96 * @var string 97 */ 98 public $transaction_charges; 99 100 /** 101 * Should custom metadata be enabled? 102 * 103 * @var bool 104 */ 105 public $custom_metadata; 106 107 /** 108 * Should the order id be sent as a custom metadata to Credo? 109 * 110 * @var bool 111 */ 112 public $meta_order_id; 113 114 /** 115 * Should the customer name be sent as a custom metadata to Credo? 116 * 117 * @var bool 118 */ 119 public $meta_name; 120 121 /** 122 * Should the billing email be sent as a custom metadata to Credo? 123 * 124 * @var bool 125 */ 126 public $meta_email; 127 128 /** 129 * Should the billing phone be sent as a custom metadata to Credo? 130 * 131 * @var bool 132 */ 133 public $meta_phone; 134 135 /** 136 * Should the billing address be sent as a custom metadata to Credo? 137 * 138 * @var bool 139 */ 140 public $meta_billing_address; 141 142 /** 143 * Should the shipping address be sent as a custom metadata to Credo? 144 * 145 * @var bool 146 */ 147 public $meta_shipping_address; 148 149 /** 150 * Should the order items be sent as a custom metadata to Credo? 151 * 152 * @var bool 153 */ 154 public $meta_products; 155 156 /** 157 * API public key 158 * 159 * @var string 160 */ 161 public $public_key; 162 163 /** 164 * API secret key 165 * 166 * @var string 167 */ 168 public $secret_key; 169 170 /** 171 * Gateway disabled message 172 * 173 * @var string 174 */ 175 public $msg; 176 /** 177 * Credo api base url 178 * 179 * @var string 180 */ 181 182 public $base_url; 183 184 /** 185 * Constructor 186 */ 187 public function __construct() { 188 $this->id = 'credo'; 189 $this->method_title = __( 'Credo', 'woo-credo' ); 190 $this->method_description = sprintf( __( 'Credo provide merchants with the tools and services needed to accept online payments from local and international customers using Mastercard, Visa, Verve Cards and Bank Transfers. <a href="%1$s" target="_blank">Sign up</a> for a Credo account, and <a href="%2$s" target="_blank">get your API keys</a>.', 'woo-credo' ), 'https://credocentral.com', 'https://credocentral.com/dashboard' ); 191 $this->has_fields = true; 192 193 $this->payment_page = $this->get_option( 'payment_page' ); 194 195 $this->supports = array( 196 'products', 9 /** 10 * Is test mode active? 11 * 12 * @var bool 13 */ 14 public $testmode; 15 16 /** 17 * Should orders be marked as complete after payment? 18 * 19 * @var bool 20 */ 21 public $autocomplete_order; 22 23 /** 24 * Credo payment page type. 25 * 26 * @var string 27 */ 28 public $payment_page; 29 30 /** 31 * Credo test public key. 32 * 33 * @var string 34 */ 35 public $test_public_key; 36 37 /** 38 * Credo test secret key. 39 * 40 * @var string 41 */ 42 public $test_secret_key; 43 44 /** 45 * Credo live public key. 46 * 47 * @var string 48 */ 49 public $live_public_key; 50 51 /** 52 * Credo live secret key. 53 * 54 * @var string 55 */ 56 public $live_secret_key; 57 58 59 60 /** 61 * Should Credo dynamic settlement be enabled. 62 * 63 * @var bool 64 */ 65 public $split_payment; 66 67 /** 68 * Should the cancel & remove order button be removed on the pay for order page. 69 * 70 * @var bool 71 */ 72 public $remove_cancel_order_button; 73 74 /** 75 * Credo service account code. 76 * 77 * @var string 78 */ 79 public $service_code; 80 81 /** 82 * Who bears Credo charges? 83 * 84 * @var string 85 */ 86 public $charges_bearer; 87 88 /** 89 * Should custom metadata be enabled? 90 * 91 * @var bool 92 */ 93 public $custom_metadata; 94 95 /** 96 * Should the order id be sent as a custom metadata to Credo? 97 * 98 * @var bool 99 */ 100 public $meta_order_id; 101 102 /** 103 * Should the customer name be sent as a custom metadata to Credo? 104 * 105 * @var bool 106 */ 107 public $meta_name; 108 109 /** 110 * Should the billing email be sent as a custom metadata to Credo? 111 * 112 * @var bool 113 */ 114 public $meta_email; 115 116 /** 117 * Should the billing phone be sent as a custom metadata to Credo? 118 * 119 * @var bool 120 */ 121 public $meta_phone; 122 123 /** 124 * Should the billing address be sent as a custom metadata to Credo? 125 * 126 * @var bool 127 */ 128 public $meta_billing_address; 129 130 /** 131 * Should the shipping address be sent as a custom metadata to Credo? 132 * 133 * @var bool 134 */ 135 public $meta_shipping_address; 136 137 /** 138 * Should the order items be sent as a custom metadata to Credo? 139 * 140 * @var bool 141 */ 142 public $meta_products; 143 144 /** 145 * API public key 146 * 147 * @var string 148 */ 149 public $public_key; 150 151 /** 152 * API secret key 153 * 154 * @var string 155 */ 156 public $secret_key; 157 158 /** 159 * Gateway disabled message 160 * 161 * @var string 162 */ 163 public $msg; 164 /** 165 * Credo api base url 166 * 167 * @var string 168 */ 169 170 public $base_url; 171 172 /** 173 * Constructor 174 */ 175 public function __construct() { 176 $this->id = 'credo'; 177 $this->method_title = __( 'Credo', 'woo-credo' ); 178 $this->method_description = sprintf( __( 'Credo provide merchants with the tools and services needed to accept online payments from local and international customers using Mastercard, Visa, Verve Cards and Bank Transfers. <a href="%1$s" target="_blank">Sign up</a> for a Credo account, and <a href="%2$s" target="_blank">get your API keys</a>.', 'woo-credo' ), 'https://credocentral.com', 'https://credocentral.com/dashboard' ); 179 $this->has_fields = true; 180 181 $this->payment_page = $this->get_option( 'payment_page' ); 182 183 $this->supports = array( 184 'products', 197 185 ); 198 186 199 // Load the form fields 200 $this->init_form_fields(); 201 202 // Load the settings 203 $this->init_settings(); 204 205 // Get setting values 206 207 $this->title = $this->get_option( 'title' ); 208 $this->description = $this->get_option( 'description' ); 209 $this->enabled = $this->get_option( 'enabled' ); 210 $this->testmode = $this->get_option( 'testmode' ) === 'yes'; 211 $this->autocomplete_order = $this->get_option( 'autocomplete_order' ) === 'yes'; 212 213 $this->test_public_key = $this->get_option( 'test_public_key' ); 214 $this->test_secret_key = $this->get_option( 'test_secret_key' ); 215 216 $this->live_public_key = $this->get_option( 'live_public_key' ); 217 $this->live_secret_key = $this->get_option( 'live_secret_key' ); 218 219 $this->saved_cards = $this->get_option( 'saved_cards' ) === 'yes'; 220 221 $this->split_payment = $this->get_option( 'split_payment' ) === 'yes'; 222 $this->remove_cancel_order_button = $this->get_option( 'remove_cancel_order_button' ) === 'yes'; 223 $this->service_code = $this->get_option( 'service_code' ); 224 $this->charges_bearer = $this->get_option( 'credo_charge_bearer' ); 225 $this->transaction_charges = $this->get_option( 'split_payment_transaction_charge' ); 226 227 $this->custom_metadata = $this->get_option( 'custom_metadata' ) === 'yes'; 228 229 $this->meta_order_id = $this->get_option( 'meta_order_id' ) === 'yes'; 230 $this->meta_name = $this->get_option( 'meta_name' ) === 'yes'; 231 $this->meta_email = $this->get_option( 'meta_email' ) === 'yes'; 232 $this->meta_phone = $this->get_option( 'meta_phone' ) === 'yes'; 233 $this->meta_billing_address = $this->get_option( 'meta_billing_address' ) === 'yes'; 234 $this->meta_shipping_address = $this->get_option( 'meta_shipping_address' ) === 'yes'; 235 $this->meta_products = $this->get_option( 'meta_products' ) === 'yes'; 236 237 $this->public_key = $this->testmode ? $this->test_public_key : $this->live_public_key; 238 $this->secret_key = $this->testmode ? $this->test_secret_key : $this->live_secret_key; 239 $this->base_url = $this->testmode ? 'https://api.public.credodemo.com' : 'https://api.credocentral.com'; 240 241 242 add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); 243 244 add_action( 'admin_notices', array( $this, 'admin_notices' ) ); 245 add_action( 246 'woocommerce_update_options_payment_gateways_' . $this->id, 247 array( 248 $this, 249 'process_admin_options', 250 ) 251 ); 252 253 add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) ); 254 255 // Payment listener/API hook. 256 add_action( 'woocommerce_api_wc_gateway_credo', array( $this, 'verify_credo_transaction' ) ); 257 258 // Webhook listener/API hook. 259 add_action( 'woocommerce_api_tbz_wc_credo_webhook', array( $this, 'process_webhooks' ) ); 260 261 // Check if the gateway can be used. 262 if ( ! $this->is_valid_for_use() ) { 263 $this->enabled = false; 264 } 265 266 } 267 268 /** 269 * Check if this gateway is enabled and available in the user's country. 270 */ 271 public function is_valid_for_use() { 272 273 if ( ! in_array( get_woocommerce_currency(), apply_filters( 'woocommerce_credo_supported_currencies', array( 274 'NGN', 275 'USD', 276 'ZAR', 277 'GHS', 278 'KES', 279 'XOF', 280 'EGP' 281 ) ) ) ) { 282 283 $this->msg = sprintf( __( 'Credo does not support your store currency. Kindly set it to either NGN (₦), GHS (₵), USD ($), KES (KSh), ZAR (R), XOF (CFA), or EGP (E£) <a href="%s">here</a>', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=general' ) ); 284 285 return false; 286 287 } 288 289 return true; 290 291 } 292 293 /** 294 * Display credo payment icon. 295 */ 296 public function get_icon() { 297 298 #$base_location = wc_get_base_location(); 187 // Load the form fields 188 $this->init_form_fields(); 189 190 // Load the settings 191 $this->init_settings(); 192 193 // Get setting values 194 195 $this->title = $this->get_option( 'title' ); 196 $this->description = $this->get_option( 'description' ); 197 $this->enabled = $this->get_option( 'enabled' ); 198 $this->testmode = $this->get_option( 'testmode' ) === 'yes'; 199 $this->autocomplete_order = $this->get_option( 'autocomplete_order' ) === 'yes'; 200 201 $this->test_public_key = $this->get_option( 'test_public_key' ); 202 $this->test_secret_key = $this->get_option( 'test_secret_key' ); 203 204 $this->live_public_key = $this->get_option( 'live_public_key' ); 205 $this->live_secret_key = $this->get_option( 'live_secret_key' ); 206 207 208 209 $this->split_payment = $this->get_option( 'split_payment' ) === 'yes'; 210 $this->remove_cancel_order_button = $this->get_option( 'remove_cancel_order_button' ) === 'yes'; 211 $this->service_code = $this->get_option( 'service_code' ); 212 $this->charges_bearer = $this->get_option( 'credo_charge_bearer' ); 213 214 215 $this->custom_metadata = $this->get_option( 'custom_metadata' ) === 'yes'; 216 217 $this->meta_order_id = $this->get_option( 'meta_order_id' ) === 'yes'; 218 $this->meta_name = $this->get_option( 'meta_name' ) === 'yes'; 219 $this->meta_email = $this->get_option( 'meta_email' ) === 'yes'; 220 $this->meta_phone = $this->get_option( 'meta_phone' ) === 'yes'; 221 $this->meta_billing_address = $this->get_option( 'meta_billing_address' ) === 'yes'; 222 $this->meta_shipping_address = $this->get_option( 'meta_shipping_address' ) === 'yes'; 223 $this->meta_products = $this->get_option( 'meta_products' ) === 'yes'; 224 225 $this->public_key = $this->testmode ? $this->test_public_key : $this->live_public_key; 226 $this->secret_key = $this->testmode ? $this->test_secret_key : $this->live_secret_key; 227 $this->base_url = $this->testmode ? 'https://api.public.credodemo.com' : 'https://api.credocentral.com'; 228 229 230 add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); 231 add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) ); 232 233 add_action( 'admin_notices', array( $this, 'admin_notices' ) ); 234 add_action( 235 'woocommerce_update_options_payment_gateways_' . $this->id, 236 array( 237 $this, 238 'process_admin_options', 239 ) 240 ); 241 242 add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) ); 243 244 // Payment listener/API hook. 245 add_action( 'woocommerce_api_wc_gateway_credo', array( $this, 'verify_credo_transaction' ) ); 246 247 // Webhook listener/API hook. 248 add_action( 'woocommerce_api_tbz_wc_credo_webhook', array( $this, 'process_webhooks' ) ); 249 250 // Check if the gateway can be used. 251 if ( ! $this->is_valid_for_use() ) { 252 $this->enabled = false; 253 } 254 255 } 256 257 /** 258 * Check if this gateway is enabled and available in the user's country. 259 */ 260 public function is_valid_for_use() { 261 262 if ( ! in_array( get_woocommerce_currency(), apply_filters( 'woocommerce_credo_supported_currencies', array( 263 'NGN', 264 'USD' 265 ) ) ) ) { 266 267 $this->msg = sprintf( __( 'Credo does not support your store currency. Kindly set it to either NGN (₦), GHS (₵), USD ($), KES (KSh), ZAR (R), XOF (CFA), or EGP (E£) <a href="%s">here</a>', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=general' ) ); 268 269 return false; 270 271 } 272 273 return true; 274 275 } 276 277 /** 278 * Display credo payment icon. 279 */ 280 public function get_icon() { 281 282 #$base_location = wc_get_base_location(); 299 283 300 284 $icon = '<img src="' . WC_HTTPS::force_https_url( plugins_url( 'assets/images/credo-wc.png', WC_CREDO_MAIN_FILE ) ) . '" alt="Credo Payment Options" />'; 301 285 302 286 303 return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id );304 305 }306 307 /**308 * Check if Credo merchant details is filled.309 */310 public function admin_notices() {311 312 if ( $this->enabled == 'no' ) {313 return;314 }315 316 // Check required fields.317 if ( ! ( $this->public_key && $this->secret_key ) ) {318 echo '<div class="error"><p>' . sprintf( __( 'Please enter your Credo merchant details <a href="%s">here</a> to be able to use the Credo WooCommerce plugin.', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=credo' ) ) . '</p></div>';319 320 return;321 }322 323 }324 325 /**326 * Check if Credo gateway is enabled.327 *328 * @return bool329 */330 public function is_available() {331 332 if ( 'yes' == $this->enabled ) {333 334 if ( ! ( $this->public_key && $this->secret_key ) ) {335 336 return false;337 338 }339 340 return true;341 342 }343 344 return false;345 346 }347 348 /**349 * Admin Panel Options.350 */351 public function admin_options() {352 353 ?>287 return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id ); 288 289 } 290 291 /** 292 * Check if Credo merchant details is filled. 293 */ 294 public function admin_notices() { 295 296 if ( $this->enabled == 'no' ) { 297 return; 298 } 299 300 // Check required fields. 301 if ( ! ( $this->public_key && $this->secret_key ) ) { 302 echo '<div class="error"><p>' . sprintf( __( 'Please enter your Credo merchant details <a href="%s">here</a> to be able to use the Credo WooCommerce plugin.', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=credo' ) ) . '</p></div>'; 303 304 return; 305 } 306 307 } 308 309 /** 310 * Check if Credo gateway is enabled. 311 * 312 * @return bool 313 */ 314 public function is_available() { 315 316 if ( 'yes' == $this->enabled ) { 317 318 if ( ! ( $this->public_key && $this->secret_key ) ) { 319 320 return false; 321 322 } 323 324 return true; 325 326 } 327 328 return false; 329 330 } 331 332 /** 333 * Admin Panel Options. 334 */ 335 public function admin_options() { 336 337 ?> 354 338 355 339 <h2><?php _e( 'Credo', 'woo-credo' ); ?> 356 <?php357 if ( function_exists( 'wc_back_link' ) ) {358 wc_back_link( __( 'Return to payments', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) );359 }360 ?>340 <?php 341 if ( function_exists( 'wc_back_link' ) ) { 342 wc_back_link( __( 'Return to payments', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ); 343 } 344 ?> 361 345 </h2> 362 346 … … 365 349 </h4> 366 350 367 <?php368 369 if ( $this->is_valid_for_use() ) {370 371 echo '<table class="form-table">';372 $this->generate_settings_html();373 echo '</table>';374 375 } else {376 ?>351 <?php 352 353 if ( $this->is_valid_for_use() ) { 354 355 echo '<table class="form-table">'; 356 $this->generate_settings_html(); 357 echo '</table>'; 358 359 } else { 360 ?> 377 361 <div class="inline error"><p> 378 362 <strong><?php _e( 'Credo Payment Gateway Disabled', 'woo-credo' ); ?></strong>: <?php echo $this->msg; ?> 379 363 </p></div> 380 364 381 <?php 382 } 383 384 } 385 386 /** 387 * Initialise Gateway Settings Form Fields. 388 */ 389 public function init_form_fields() { 390 391 $form_fields = array( 392 'enabled' => array( 393 'title' => __( 'Enable/Disable', 'woo-credo' ), 394 'label' => __( 'Enable Credo', 'woo-credo' ), 395 'type' => 'checkbox', 396 'description' => __( 'Enable Credo as a payment option on the checkout page.', 'woo-credo' ), 397 'default' => 'no', 398 'desc_tip' => true, 399 ), 400 'title' => array( 401 'title' => __( 'Title', 'woo-credo' ), 402 'type' => 'text', 403 'description' => __( 'This controls the payment method title which the user sees during checkout.', 'woo-credo' ), 404 'default' => __( 'Card/ Bank Transfer', 'woo-credo' ), 405 'desc_tip' => true, 406 ), 407 'description' => array( 408 'title' => __( 'Description', 'woo-credo' ), 409 'type' => 'textarea', 410 'description' => __( 'This controls the payment method description which the user sees during checkout.', 'woo-credo' ), 411 'default' => __( 'Make payment using your debit and credit cards', 'woo-credo' ), 412 'desc_tip' => true, 413 ), 414 'testmode' => array( 415 'title' => __( 'Test mode', 'woo-credo' ), 416 'label' => __( 'Enable Test Mode', 'woo-credo' ), 417 'type' => 'checkbox', 418 'description' => __( 'Test mode enables you to test payments before going live. <br />Once the LIVE MODE is enabled on your Credo account uncheck this.', 'woo-credo' ), 419 'default' => 'yes', 420 'desc_tip' => true, 421 ), 422 'payment_page' => array( 423 'title' => __( 'Payment Option', 'woo-credo' ), 424 'type' => 'select', 425 'description' => __( 'Redirect will redirect the customer to credo gateway.', 'woo-credo' ), 426 'default' => '', 427 'desc_tip' => false, 428 'options' => array( 429 'redirect' => __( 'Redirect', 'woo-credo' ), 430 ), 431 ), 432 'test_secret_key' => array( 433 'title' => __( 'Test Secret Key', 'woo-credo' ), 434 'type' => 'password', 435 'description' => __( 'Enter your Test Secret Key here', 'woo-credo' ), 436 'default' => '', 437 ), 438 'test_public_key' => array( 439 'title' => __( 'Test Public Key', 'woo-credo' ), 440 'type' => 'text', 441 'description' => __( 'Enter your Test Public Key here.', 'woo-credo' ), 442 'default' => '', 443 ), 444 'live_secret_key' => array( 445 'title' => __( 'Live Secret Key', 'woo-credo' ), 446 'type' => 'password', 447 'description' => __( 'Enter your Live Secret Key here.', 'woo-credo' ), 448 'default' => '', 449 ), 450 'live_public_key' => array( 451 'title' => __( 'Live Public Key', 'woo-credo' ), 452 'type' => 'text', 453 'description' => __( 'Enter your Live Public Key here.', 'woo-credo' ), 454 'default' => '', 455 ), 456 'autocomplete_order' => array( 457 'title' => __( 'Autocomplete Order After Payment', 'woo-credo' ), 458 'label' => __( 'Autocomplete Order', 'woo-credo' ), 459 'type' => 'checkbox', 460 'class' => 'wc-credo-autocomplete-order', 461 'description' => __( 'If enabled, the order will be marked as complete after successful payment', 'woo-credo' ), 462 'default' => 'no', 463 'desc_tip' => true, 464 ), 465 'remove_cancel_order_button' => array( 466 'title' => __( 'Remove Cancel Order & Restore Cart Button', 'woo-credo' ), 467 'label' => __( 'Remove the cancel order & restore cart button on the pay for order page', 'woo-credo' ), 468 'type' => 'checkbox', 469 'description' => '', 470 'default' => 'no', 471 ), 472 'split_payment' => array( 473 'title' => __( 'Dynamic Settlement', 'woo-credo' ), 474 'label' => __( 'Enable Dynamic Settlement', 'woo-credo' ), 475 'type' => 'checkbox', 476 'description' => __('Dynamic settlement splits allow you to distribute funds from a single transaction among multiple recipients/accounts based on predefined rules. 365 <?php 366 } 367 368 } 369 370 /** 371 * Initialise Gateway Settings Form Fields. 372 */ 373 public function init_form_fields() { 374 375 $form_fields = array( 376 'enabled' => array( 377 'title' => __( 'Enable/Disable', 'woo-credo' ), 378 'label' => __( 'Enable Credo', 'woo-credo' ), 379 'type' => 'checkbox', 380 'description' => __( 'Enable Credo as a payment option on the checkout page.', 'woo-credo' ), 381 'default' => 'no', 382 'desc_tip' => true, 383 ), 384 'title' => array( 385 'title' => __( 'Title', 'woo-credo' ), 386 'type' => 'text', 387 'description' => __( 'This controls the payment method title which the user sees during checkout.', 'woo-credo' ), 388 'default' => __( 'Card/ Bank Transfer', 'woo-credo' ), 389 'desc_tip' => true, 390 ), 391 'description' => array( 392 'title' => __( 'Description', 'woo-credo' ), 393 'type' => 'textarea', 394 'description' => __( 'This controls the payment method description which the user sees during checkout.', 'woo-credo' ), 395 'default' => __( 'Make payment using your debit and credit cards', 'woo-credo' ), 396 'desc_tip' => true, 397 ), 398 'testmode' => array( 399 'title' => __( 'Test mode', 'woo-credo' ), 400 'label' => __( 'Enable Test Mode', 'woo-credo' ), 401 'type' => 'checkbox', 402 'description' => __( 'Test mode enables you to test payments before going live. <br />Once the LIVE MODE is enabled on your Credo account uncheck this.', 'woo-credo' ), 403 'default' => 'yes', 404 'desc_tip' => true, 405 ), 406 'payment_page' => array( 407 'title' => __( 'Payment Option', 'woo-credo' ), 408 'type' => 'select', 409 'description' => __( 'Redirect will redirect the customer to credo gateway.', 'woo-credo' ), 410 'default' => '', 411 'desc_tip' => false, 412 'options' => array( 413 'redirect' => __( 'Redirect', 'woo-credo' ), 414 'pop up' => __('Pop up', 'woo-credo'), 415 416 ), 417 ), 418 'test_secret_key' => array( 419 'title' => __( 'Test Secret Key', 'woo-credo' ), 420 'type' => 'password', 421 'description' => __( 'Enter your Test Secret Key here', 'woo-credo' ), 422 'default' => '', 423 ), 424 'test_public_key' => array( 425 'title' => __( 'Test Public Key', 'woo-credo' ), 426 'type' => 'text', 427 'description' => __( 'Enter your Test Public Key here.', 'woo-credo' ), 428 'default' => '', 429 ), 430 'live_secret_key' => array( 431 'title' => __( 'Live Secret Key', 'woo-credo' ), 432 'type' => 'password', 433 'description' => __( 'Enter your Live Secret Key here.', 'woo-credo' ), 434 'default' => '', 435 ), 436 'live_public_key' => array( 437 'title' => __( 'Live Public Key', 'woo-credo' ), 438 'type' => 'text', 439 'description' => __( 'Enter your Live Public Key here.', 'woo-credo' ), 440 'default' => '', 441 ), 442 'autocomplete_order' => array( 443 'title' => __( 'Autocomplete Order After Payment', 'woo-credo' ), 444 'label' => __( 'Autocomplete Order', 'woo-credo' ), 445 'type' => 'checkbox', 446 'class' => 'wc-credo-autocomplete-order', 447 'description' => __( 'If enabled, the order will be marked as complete after successful payment', 'woo-credo' ), 448 'default' => 'no', 449 'desc_tip' => true, 450 ), 451 'remove_cancel_order_button' => array( 452 'title' => __( 'Remove Cancel Order & Restore Cart Button', 'woo-credo' ), 453 'label' => __( 'Remove the cancel order & restore cart button on the pay for order page', 'woo-credo' ), 454 'type' => 'checkbox', 455 'description' => '', 456 'default' => 'no', 457 ), 458 'split_payment' => array( 459 'title' => __( 'Dynamic Settlement', 'woo-credo' ), 460 'label' => __( 'Enable Dynamic Settlement', 'woo-credo' ), 461 'type' => 'checkbox', 462 'description' => __('Dynamic settlement splits allow you to distribute funds from a single transaction among multiple recipients/accounts based on predefined rules. 477 463 478 464 These rules can consider various factors like percentages, or fixed amounts. The dynamic nature ensures that splits adapt in real-time to changing circumstances. '), 479 'class' => 'woocommerce_credo_split_payment', 480 'default' => 'no', 481 'desc_tip' => true, 482 ), 483 'service_code' => array( 484 'title' => __( 'Service Code', 'woo-credo' ), 485 'type' => 'text', 486 'description' => __( 'Enter your service code here.', 'woo-credo' ), 487 'class' => 'woocommerce_credo_subaccount_code', 488 'default' => '', 489 ), 490 491 492 'credo_charge_bearer' => array( 493 'title' => __( 'Credo Charges Bearer', 'woo-credo' ), 494 'type' => 'select', 495 'description' => __( 'Who bears Credo charges?', 'woo-credo' ), 496 497 498 499 465 'class' => 'woocommerce_credo_split_payment', 466 'default' => 'no', 467 'desc_tip' => true, 468 ), 469 'service_code' => array( 470 'title' => __( 'Service Code', 'woo-credo' ), 471 'type' => 'text', 472 'description' => __( 'Enter your service code here.', 'woo-credo' ), 473 'class' => 'woocommerce_credo_subaccount_code', 500 474 'default' => '', 501 'desc_tip' => false, 502 'options' => array( 503 504 'customer' => __( 'Customer', 'woo-credo' ), 505 'merchant' => __( 'Merchant', 'woo-credo' ), 506 ), 507 ), 508 509 'custom_metadata' => array( 510 'title' => __( 'Custom Metadata', 'woo-credo' ), 511 'label' => __( 'Enable Custom Metadata', 'woo-credo' ), 512 'type' => 'checkbox', 513 'class' => 'wc-credo-metadata', 514 'description' => __( 'If enabled, you will be able to send more information about the order to Credo.', 'woo-credo' ), 515 'default' => 'no', 516 'desc_tip' => true, 517 ), 518 'meta_order_id' => array( 519 'title' => __( 'Order ID', 'woo-credo' ), 520 'label' => __( 'Send Order ID', 'woo-credo' ), 521 'type' => 'checkbox', 522 'class' => 'wc-credo-meta-order-id', 523 'description' => __( 'If checked, the Order ID will be sent to Credo', 'woo-credo' ), 524 'default' => 'no', 525 'desc_tip' => true, 526 ), 527 'meta_name' => array( 528 'title' => __( 'Customer Name', 'woo-credo' ), 529 'label' => __( 'Send Customer Name', 'woo-credo' ), 530 'type' => 'checkbox', 531 'class' => 'wc-credo-meta-name', 532 'description' => __( 'If checked, the customer full name will be sent to Credo', 'woo-credo' ), 533 'default' => 'no', 534 'desc_tip' => true, 535 ), 536 'meta_email' => array( 537 'title' => __( 'Customer Email', 'woo-credo' ), 538 'label' => __( 'Send Customer Email', 'woo-credo' ), 539 'type' => 'checkbox', 540 'class' => 'wc-credo-meta-email', 541 'description' => __( 'If checked, the customer email address will be sent to Credo', 'woo-credo' ), 542 'default' => 'no', 543 'desc_tip' => true, 544 ), 545 'meta_phone' => array( 546 'title' => __( 'Customer Phone', 'woo-credo' ), 547 'label' => __( 'Send Customer Phone', 'woo-credo' ), 548 'type' => 'checkbox', 549 'class' => 'wc-credo-meta-phone', 550 'description' => __( 'If checked, the customer phone will be sent to Credo', 'woo-credo' ), 551 'default' => 'no', 552 'desc_tip' => true, 553 ), 554 'meta_billing_address' => array( 555 'title' => __( 'Order Billing Address', 'woo-credo' ), 556 'label' => __( 'Send Order Billing Address', 'woo-credo' ), 557 'type' => 'checkbox', 558 'class' => 'wc-credo-meta-billing-address', 559 'description' => __( 'If checked, the order billing address will be sent to Credo', 'woo-credo' ), 560 'default' => 'no', 561 'desc_tip' => true, 562 ), 563 'meta_shipping_address' => array( 564 'title' => __( 'Order Shipping Address', 'woo-credo' ), 565 'label' => __( 'Send Order Shipping Address', 'woo-credo' ), 566 'type' => 'checkbox', 567 'class' => 'wc-credo-meta-shipping-address', 568 'description' => __( 'If checked, the order shipping address will be sent to Credo', 'woo-credo' ), 569 'default' => 'no', 570 'desc_tip' => true, 571 ), 572 'meta_products' => array( 573 'title' => __( 'Product(s) Purchased', 'woo-credo' ), 574 'label' => __( 'Send Product(s) Purchased', 'woo-credo' ), 575 'type' => 'checkbox', 576 'class' => 'wc-credo-meta-products', 577 'description' => __( 'If checked, the product(s) purchased will be sent to Credo', 'woo-credo' ), 578 'default' => 'no', 579 'desc_tip' => true, 580 ), 581 ); 582 583 if ( 'NGN' !== get_woocommerce_currency() ) { 584 unset( $form_fields['custom_gateways'] ); 585 } 586 587 $this->form_fields = $form_fields; 588 589 } 590 591 /** 592 * Payment form on checkout page 593 */ 594 public function payment_fields() { 595 596 if ( $this->description ) { 597 echo wpautop( wptexturize( $this->description ) ); 598 } 599 600 if ( ! is_ssl() ) { 601 return; 602 } 603 604 if ( $this->supports( 'tokenization' ) && is_checkout() && $this->saved_cards && is_user_logged_in() ) { 605 $this->tokenization_script(); 606 $this->saved_payment_methods(); 607 $this->save_payment_method_checkbox(); 608 } 609 610 } 611 612 /** 613 * Outputs scripts used for credo payment. 614 */ 615 616 617 /** 618 * Load admin scripts. 619 */ 620 public function admin_scripts() { 621 622 if ( 'woocommerce_page_wc-settings' !== get_current_screen()->id ) { 623 return; 624 } 625 626 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 627 628 $credo_admin_params = array( 629 'plugin_url' => WC_CREDO_URL, 630 ); 631 632 wp_enqueue_script( 'wc_credo_admin', plugins_url( 'assets/js/credo-admin' . $suffix . '.js', WC_CREDO_MAIN_FILE ), array(), WC_CREDO_VERSION, true ); 633 634 wp_localize_script( 'wc_credo_admin', 'wc_credo_admin_params', $credo_admin_params ); 635 636 } 637 638 /** 639 * Process the payment. 640 * 641 * @param int $order_id 642 * 643 * @return array|void 644 */ 645 public function process_payment( $order_id ) { 646 647 if ( 'redirect' === $this->payment_page ) { 648 649 return $this->process_redirect_payment_option( $order_id ); 650 651 } 652 653 } 654 655 /** 656 * Process a redirect payment option payment. 657 * 658 * @param int $order_id 659 * 660 * @return array|void 661 * @since 5.7 662 */ 663 public function process_redirect_payment_option( $order_id ) { 664 665 $order = wc_get_order( $order_id ); 666 $amount = $order->get_total() * 100; 667 $txnref = $order_id . '_' . time(); 668 $callback_url = WC()->api_request_url( 'WC_Gateway_Credo' ); 669 670 $payment_channels = $this->get_gateway_payment_channels( $order ); 671 672 673 $credo_params = array( 674 'amount' => $amount, 675 'email' => $order->get_billing_email(), 676 'currency' => $order->get_currency(), 677 'reference' => $txnref, 678 'callbackUrl' => $callback_url, 679 'customerFirstName' => $order->get_billing_first_name(), 680 'customerLastName' => $order->get_billing_last_name(), 681 'customerPhoneNumber' => $order->get_billing_phone(), 682 683 684 ); 685 686 if ( ! empty( $payment_channels ) ) { 687 $credo_params['channels'] = $payment_channels; 688 } 689 690 $credo_params['bearer'] = $this->charges_bearer === 'customer' ? 0 : 1; 691 692 693 if ( $this->split_payment && !empty( $this->service_code ) ) { 694 $credo_params['serviceCode'] = $this->service_code; 695 } 696 697 $credo_params['metadata']['custom_fields'] = $this->get_custom_fields( $order_id ); 698 $credo_params['metadata']['cancel_action'] = wc_get_cart_url(); 699 700 $order->update_meta_data( '_credo_txn_ref', $txnref ); 701 $order->save(); 702 703 $credo_url = $this->base_url . '/transaction/initialize'; 704 705 $headers = array( 706 'Authorization' => $this->public_key, 707 'Content-Type' => 'application/json', 708 ); 709 710 $args = array( 711 'headers' => $headers, 712 'timeout' => 60, 713 'body' => json_encode( $credo_params ), 714 ); 715 716 $request = wp_remote_post( $credo_url, $args ); 717 718 if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) { 719 720 $credo_response = json_decode( wp_remote_retrieve_body( $request ) ); 721 echo '<script>console.log("PHP error: ' . json_encode( $credo_params ) . '")</script>'; 722 723 return array( 724 'result' => 'success', 725 'redirect' => $credo_response->data->authorizationUrl, 726 ); 727 728 } else { 729 wc_add_notice( __( 'Unable to process payment try again', 'woo-credo' ), 'error' ); 730 731 $credo_response = wp_remote_retrieve_body( $request ); 732 echo '<script>console.log("PHP error: ' . $credo_response . '")</script>'; 733 734 return; 735 } 736 737 } 738 739 740 /** 741 * Show new card can only be added when placing an order notice. 742 */ 743 public function add_payment_method() { 744 745 wc_add_notice( __( 'You can only add a new card when placing an order.', 'woo-credo' ), 'error' ); 746 747 return; 748 749 } 750 751 /** 752 * Displays the payment page. 753 * 754 * @param $order_id 755 */ 756 public function receipt_page( $order_id ) { 757 758 $order = wc_get_order( $order_id ); 759 760 echo '<div id="wc-credo-form">'; 761 762 echo '<p>' . __( 'Thank you for your order, please click the button below to pay with Credo.', 'woo-credo' ) . '</p>'; 763 764 echo '<div id="credo_form"><form id="order_review" method="post" action="' . WC()->api_request_url( 'WC_Gateway_Credo' ) . '"></form><button class="button" id="credo-payment-button">' . __( 'Pay Now', 'woo-credo' ) . '</button>'; 765 766 if ( ! $this->remove_cancel_order_button ) { 767 echo ' <a class="button cancel" id="credo-cancel-payment-button" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order & restore cart', 'woo-credo' ) . '</a></div>'; 768 } 769 770 echo '</div>'; 771 772 } 773 774 /** 775 * Verify Credo payment. 776 */ 777 public function verify_credo_transaction() { 778 779 if ( isset( $_REQUEST['transRef'] ) ) { 780 $credo_txn_ref = sanitize_text_field( $_REQUEST['transRef'] ); 781 } elseif ( isset( $_REQUEST['reference'] ) ) { 782 $credo_txn_ref = sanitize_text_field( $_REQUEST['reference'] ); 783 } else { 784 $credo_txn_ref = false; 785 } 786 787 @ob_clean(); 788 789 if ( $credo_txn_ref ) { 790 791 $credo_response = $this->get_credo_transaction( $credo_txn_ref ); 792 793 if ( false !== $credo_response ) { 794 795 if ( 0 == $credo_response->data->status ) { 796 797 $order_details = explode( '_', $credo_response->data->businessRef ); 798 $order_id = (int) $order_details[0]; 799 $order = wc_get_order( $order_id ); 800 801 if ( in_array( $order->get_status(), array( 'processing', 'completed', 'on-hold' ) ) ) { 802 803 wp_redirect( $this->get_return_url( $order ) ); 804 805 exit; 806 807 } 808 809 $order_total = $order->get_total(); 810 $order_currency = $order->get_currency(); 811 $currency_symbol = get_woocommerce_currency_symbol( $order_currency ); 812 $amount_paid = $credo_response->data->transAmount; 813 $credo_ref = $credo_response->data->transRef; 814 $payment_currency = strtoupper( $credo_response->data->currencyCode ); 815 $gateway_symbol = get_woocommerce_currency_symbol( $payment_currency ); 816 817 // check if the amount paid is equal to the order amount. 818 if ( $amount_paid < $order_total ) { 819 820 $order->update_status( 'on-hold', '' ); 821 822 $order->add_meta_data( '_transaction_id', $credo_ref, true ); 823 824 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment transaction was successful, but the amount paid is not the same as the total order amount.%2$sYour order is currently on hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 825 $notice_type = 'notice'; 826 827 // Add Customer Order Note 828 $order->add_order_note( $notice, 1 ); 829 830 // Add Admin Order Note 831 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Amount paid is less than the total order amount.%3$sAmount Paid was <strong>%4$s (%5$s)</strong> while the total order amount is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $currency_symbol, $amount_paid, $currency_symbol, $order_total, '<br />', $credo_ref ); 832 $order->add_order_note( $admin_order_note ); 833 834 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 835 836 wc_add_notice( $notice, $notice_type ); 837 838 } else { 839 840 if ( $payment_currency !== $order_currency ) { 841 842 $order->update_status( 'on-hold', '' ); 843 844 $order->update_meta_data( '_transaction_id', $credo_ref ); 845 846 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment was successful, but the payment currency is different from the order currency.%2$sYour order is currently on-hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 847 $notice_type = 'notice'; 848 849 // Add Customer Order Note 850 $order->add_order_note( $notice, 1 ); 851 852 // Add Admin Order Note 853 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Order currency is different from the payment currency.%3$sOrder Currency is <strong>%4$s (%5$s)</strong> while the payment currency is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $order_currency, $currency_symbol, $payment_currency, $gateway_symbol, '<br />', $credo_ref ); 854 $order->add_order_note( $admin_order_note ); 855 856 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 857 858 wc_add_notice( $notice, $notice_type ); 859 860 } else { 861 862 $order->payment_complete( $credo_ref ); 863 $order->add_order_note( sprintf( __( 'Payment via Credo successful (Transaction Reference: %s)', 'woo-credo' ), $credo_ref ) ); 864 865 if ( $this->is_autocomplete_order_enabled( $order ) ) { 866 $order->update_status( 'completed' ); 867 } 868 } 869 } 870 871 $order->save(); 872 873 874 WC()->cart->empty_cart(); 875 876 } else { 877 878 $order_details = explode( '_', $_REQUEST['reference'] ); 879 880 $order_id = (int) $order_details[0]; 881 882 $order = wc_get_order( $order_id ); 883 884 $order->update_status( 'failed', __( 'Payment was declined by Credo.', 'woo-credo' ) ); 885 886 } 887 } 888 889 wp_redirect( $this->get_return_url( $order ) ); 890 891 exit; 892 } 893 894 wp_redirect( wc_get_page_permalink( 'cart' ) ); 895 896 exit; 897 898 } 899 900 /** 901 * Process Webhook. 902 */ 903 public function process_webhooks() { 904 905 if ( ! array_key_exists( 'HTTP_X_CREDO_SIGNATURE', $_SERVER ) || ( strtoupper( $_SERVER['REQUEST_METHOD'] ) !== 'POST' ) ) { 906 exit; 907 } 908 909 $json = file_get_contents( 'php://input' ); 910 911 // validate event do all at once to avoid timing attack. 912 if ( $_SERVER['HTTP_X_CREDO_SIGNATURE'] !== hash_hmac( 'sha512', $json, $this->secret_key ) ) { 913 exit; 914 } 915 916 $event = json_decode( $json ); 917 918 if ( 'charge.success' !== strtolower( $event->event ) ) { 919 return; 920 } 921 922 sleep( 10 ); 923 924 $credo_response = $this->get_credo_transaction( $event->data->reference ); 925 926 if ( false === $credo_response ) { 927 return; 928 } 929 930 $order_details = explode( '_', $credo_response->data->reference ); 931 932 $order_id = (int) $order_details[0]; 933 934 $order = wc_get_order( $order_id ); 935 936 if ( ! $order ) { 937 return; 938 } 939 940 $credo_txn_ref = $order->get_meta( '_credo_txn_ref' ); 941 942 if ( $credo_response->data->reference != $credo_txn_ref ) { 943 exit; 944 } 945 946 http_response_code( 200 ); 947 948 if ( in_array( strtolower( $order->get_status() ), array( 'processing', 'completed', 'on-hold' ), true ) ) { 949 exit; 950 } 951 952 $order_currency = $order->get_currency(); 953 954 $currency_symbol = get_woocommerce_currency_symbol( $order_currency ); 955 956 $order_total = $order->get_total(); 957 958 $amount_paid = $credo_response->data->amount / 100; 959 960 $credo_ref = $credo_response->data->reference; 961 962 $payment_currency = strtoupper( $credo_response->data->currency ); 963 964 $gateway_symbol = get_woocommerce_currency_symbol( $payment_currency ); 965 966 // check if the amount paid is equal to the order amount. 967 if ( $amount_paid < $order_total ) { 968 969 $order->update_status( 'on-hold', '' ); 970 971 $order->add_meta_data( '_transaction_id', $credo_ref, true ); 972 973 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment transaction was successful, but the amount paid is not the same as the total order amount.%2$sYour order is currently on hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 974 $notice_type = 'notice'; 975 976 // Add Customer Order Note. 977 $order->add_order_note( $notice, 1 ); 978 979 // Add Admin Order Note. 980 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Amount paid is less than the total order amount.%3$sAmount Paid was <strong>%4$s (%5$s)</strong> while the total order amount is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $currency_symbol, $amount_paid, $currency_symbol, $order_total, '<br />', $credo_ref ); 981 $order->add_order_note( $admin_order_note ); 982 983 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 984 985 wc_add_notice( $notice, $notice_type ); 986 987 WC()->cart->empty_cart(); 988 989 } else { 990 991 if ( $payment_currency !== $order_currency ) { 992 993 $order->update_status( 'on-hold', '' ); 994 995 $order->update_meta_data( '_transaction_id', $credo_ref ); 996 997 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment was successful, but the payment currency is different from the order currency.%2$sYour order is currently on-hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 998 $notice_type = 'notice'; 999 1000 // Add Customer Order Note. 1001 $order->add_order_note( $notice, 1 ); 1002 1003 // Add Admin Order Note. 1004 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Order currency is different from the payment currency.%3$sOrder Currency is <strong>%4$s (%5$s)</strong> while the payment currency is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $order_currency, $currency_symbol, $payment_currency, $gateway_symbol, '<br />', $credo_ref ); 1005 $order->add_order_note( $admin_order_note ); 1006 1007 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 1008 1009 wc_add_notice( $notice, $notice_type ); 1010 1011 } else { 1012 1013 $order->payment_complete( $credo_ref ); 1014 1015 $order->add_order_note( sprintf( __( 'Payment via Credo successful (Transaction Reference: %s)', 'woo-credo' ), $credo_ref ) ); 1016 1017 WC()->cart->empty_cart(); 1018 1019 if ( $this->is_autocomplete_order_enabled( $order ) ) { 1020 $order->update_status( 'completed' ); 1021 } 1022 } 1023 } 1024 1025 $order->save(); 1026 1027 $this->save_card_details( $credo_response, $order->get_user_id(), $order_id ); 1028 1029 exit; 1030 } 1031 1032 1033 /** 1034 * Get custom fields to pass to Credo. 1035 * 1036 * @param int $order_id WC Order ID 1037 * 1038 * @return array 1039 */ 1040 public function get_custom_fields( $order_id ) { 1041 1042 $order = wc_get_order( $order_id ); 1043 1044 $custom_fields = array(); 1045 1046 $custom_fields[] = array( 1047 'display_name' => 'Plugin', 1048 'variable_name' => 'plugin', 1049 'value' => 'woo-credo', 1050 ); 1051 1052 if ( $this->custom_metadata ) { 1053 1054 if ( $this->meta_order_id ) { 1055 1056 $custom_fields[] = array( 1057 'display_name' => 'Order ID', 1058 'variable_name' => 'order_id', 1059 'value' => $order_id, 1060 ); 1061 1062 } 1063 1064 if ( $this->meta_name ) { 1065 1066 $custom_fields[] = array( 1067 'display_name' => 'Customer Name', 1068 'variable_name' => 'customer_name', 1069 'value' => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(), 1070 ); 1071 1072 } 1073 1074 if ( $this->meta_email ) { 1075 1076 $custom_fields[] = array( 1077 'display_name' => 'Customer Email', 1078 'variable_name' => 'customer_email', 1079 'value' => $order->get_billing_email(), 1080 ); 1081 1082 } 1083 1084 if ( $this->meta_phone ) { 1085 1086 $custom_fields[] = array( 1087 'display_name' => 'Customer Phone', 1088 'variable_name' => 'customer_phone', 1089 'value' => $order->get_billing_phone(), 1090 ); 1091 1092 } 1093 1094 if ( $this->meta_products ) { 1095 1096 $line_items = $order->get_items(); 1097 1098 $products = ''; 1099 1100 foreach ( $line_items as $item_id => $item ) { 1101 $name = $item['name']; 1102 $quantity = $item['qty']; 1103 $products .= $name . ' (Qty: ' . $quantity . ')'; 1104 $products .= ' | '; 1105 } 1106 1107 $products = rtrim( $products, ' | ' ); 1108 1109 $custom_fields[] = array( 1110 'display_name' => 'Products', 1111 'variable_name' => 'products', 1112 'value' => $products, 1113 ); 1114 1115 } 1116 1117 if ( $this->meta_billing_address ) { 1118 1119 $billing_address = $order->get_formatted_billing_address(); 1120 $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) ); 1121 1122 $credo_params['meta_billing_address'] = $billing_address; 1123 1124 $custom_fields[] = array( 1125 'display_name' => 'Billing Address', 1126 'variable_name' => 'billing_address', 1127 'value' => $billing_address, 1128 ); 1129 1130 } 1131 1132 if ( $this->meta_shipping_address ) { 1133 1134 $shipping_address = $order->get_formatted_shipping_address(); 1135 $shipping_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $shipping_address ) ); 1136 1137 if ( empty( $shipping_address ) ) { 1138 1139 $billing_address = $order->get_formatted_billing_address(); 1140 $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) ); 1141 1142 $shipping_address = $billing_address; 1143 1144 } 1145 $custom_fields[] = array( 1146 'display_name' => 'Shipping Address', 1147 'variable_name' => 'shipping_address', 1148 'value' => $shipping_address, 1149 ); 1150 1151 } 1152 1153 } 1154 1155 return $custom_fields; 1156 } 1157 1158 1159 /** 1160 * Checks if WC version is less than passed in version. 1161 * 1162 * @param string $version Version to check against. 1163 * 1164 * @return bool 1165 */ 1166 public function is_wc_lt( $version ) { 1167 return version_compare( WC_VERSION, $version, '<' ); 1168 } 1169 1170 /** 1171 * Checks if autocomplete order is enabled for the payment method. 1172 * 1173 * @param WC_Order $order Order object. 1174 * 1175 * @return bool 1176 * @since 5.7 1177 */ 1178 protected function is_autocomplete_order_enabled( $order ) { 1179 $autocomplete_order = false; 1180 1181 $payment_method = $order->get_payment_method(); 1182 1183 $credo_settings = get_option( 'woocommerce_' . $payment_method . '_settings' ); 1184 1185 if ( isset( $credo_settings['autocomplete_order'] ) && 'yes' === $credo_settings['autocomplete_order'] ) { 1186 $autocomplete_order = true; 1187 } 1188 1189 return $autocomplete_order; 1190 } 1191 1192 /** 1193 * Retrieve the payment channels configured for the gateway 1194 * 1195 * @param WC_Order $order Order object. 1196 * 1197 * @return array 1198 * @since 5.7 1199 */ 1200 protected function get_gateway_payment_channels( $order ) { 1201 1202 $payment_method = $order->get_payment_method(); 1203 1204 if ( 'credo' === $payment_method ) { 1205 return array(); 1206 } 1207 1208 $payment_channels = $this->payment_channels; 1209 1210 if ( empty( $payment_channels ) ) { 1211 $payment_channels = array( 'card' ); 1212 } 1213 1214 return $payment_channels; 1215 } 1216 1217 /** 1218 * Retrieve a transaction from Credo. 1219 * 1220 * @param $credo_txn_ref 1221 * 1222 * @return false|mixed 1223 * @since 5.7.5 1224 */ 1225 private function get_credo_transaction( $credo_txn_ref ) { 1226 1227 $credo_url = $this->base_url . '/transaction/' . $credo_txn_ref . '/verify'; 1228 1229 $headers = array( 1230 'Authorization' => $this->secret_key, 1231 ); 1232 1233 $args = array( 1234 'headers' => $headers, 1235 'timeout' => 60, 1236 ); 1237 1238 $request = wp_remote_get( $credo_url, $args ); 1239 1240 if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) { 1241 return json_decode( wp_remote_retrieve_body( $request ) ); 1242 } 1243 1244 return false; 1245 } 475 ), 476 477 478 'credo_charge_bearer' => array( 479 'title' => __( 'Credo Charges Bearer', 'woo-credo' ), 480 'type' => 'select', 481 'description' => __( 'Who bears Credo charges?', 'woo-credo' ), 482 483 484 485 486 'default' => '', 487 'desc_tip' => false, 488 'options' => array( 489 490 'customer' => __( 'Customer', 'woo-credo' ), 491 'merchant' => __( 'Merchant', 'woo-credo' ), 492 ), 493 ), 494 495 'custom_metadata' => array( 496 'title' => __( 'Custom Metadata', 'woo-credo' ), 497 'label' => __( 'Enable Custom Metadata', 'woo-credo' ), 498 'type' => 'checkbox', 499 'class' => 'wc-credo-metadata', 500 'description' => __( 'If enabled, you will be able to send more information about the order to Credo.', 'woo-credo' ), 501 'default' => 'no', 502 'desc_tip' => true, 503 ), 504 'meta_order_id' => array( 505 'title' => __( 'Order ID', 'woo-credo' ), 506 'label' => __( 'Send Order ID', 'woo-credo' ), 507 'type' => 'checkbox', 508 'class' => 'wc-credo-meta-order-id', 509 'description' => __( 'If checked, the Order ID will be sent to Credo', 'woo-credo' ), 510 'default' => 'no', 511 'desc_tip' => true, 512 ), 513 'meta_name' => array( 514 'title' => __( 'Customer Name', 'woo-credo' ), 515 'label' => __( 'Send Customer Name', 'woo-credo' ), 516 'type' => 'checkbox', 517 'class' => 'wc-credo-meta-name', 518 'description' => __( 'If checked, the customer full name will be sent to Credo', 'woo-credo' ), 519 'default' => 'no', 520 'desc_tip' => true, 521 ), 522 'meta_email' => array( 523 'title' => __( 'Customer Email', 'woo-credo' ), 524 'label' => __( 'Send Customer Email', 'woo-credo' ), 525 'type' => 'checkbox', 526 'class' => 'wc-credo-meta-email', 527 'description' => __( 'If checked, the customer email address will be sent to Credo', 'woo-credo' ), 528 'default' => 'no', 529 'desc_tip' => true, 530 ), 531 'meta_phone' => array( 532 'title' => __( 'Customer Phone', 'woo-credo' ), 533 'label' => __( 'Send Customer Phone', 'woo-credo' ), 534 'type' => 'checkbox', 535 'class' => 'wc-credo-meta-phone', 536 'description' => __( 'If checked, the customer phone will be sent to Credo', 'woo-credo' ), 537 'default' => 'no', 538 'desc_tip' => true, 539 ), 540 'meta_billing_address' => array( 541 'title' => __( 'Order Billing Address', 'woo-credo' ), 542 'label' => __( 'Send Order Billing Address', 'woo-credo' ), 543 'type' => 'checkbox', 544 'class' => 'wc-credo-meta-billing-address', 545 'description' => __( 'If checked, the order billing address will be sent to Credo', 'woo-credo' ), 546 'default' => 'no', 547 'desc_tip' => true, 548 ), 549 'meta_shipping_address' => array( 550 'title' => __( 'Order Shipping Address', 'woo-credo' ), 551 'label' => __( 'Send Order Shipping Address', 'woo-credo' ), 552 'type' => 'checkbox', 553 'class' => 'wc-credo-meta-shipping-address', 554 'description' => __( 'If checked, the order shipping address will be sent to Credo', 'woo-credo' ), 555 'default' => 'no', 556 'desc_tip' => true, 557 ), 558 'meta_products' => array( 559 'title' => __( 'Product(s) Purchased', 'woo-credo' ), 560 'label' => __( 'Send Product(s) Purchased', 'woo-credo' ), 561 'type' => 'checkbox', 562 'class' => 'wc-credo-meta-products', 563 'description' => __( 'If checked, the product(s) purchased will be sent to Credo', 'woo-credo' ), 564 'default' => 'no', 565 'desc_tip' => true, 566 ), 567 ); 568 569 if ( 'NGN' !== get_woocommerce_currency() ) { 570 unset( $form_fields['custom_gateways'] ); 571 } 572 573 $this->form_fields = $form_fields; 574 575 } 576 577 /** 578 * Payment form on checkout page 579 */ 580 public function payment_fields() { 581 582 if ( $this->description ) { 583 echo wpautop( wptexturize( $this->description ) ); 584 } 585 586 if ( ! is_ssl() ) { 587 return; 588 } 589 590 591 592 } 593 594 /** 595 * Outputs scripts used for credo payment. 596 */ 597 598 599 /** 600 * Load admin scripts. 601 */ 602 603 public function payment_scripts() { 604 605 if ( isset( $_GET['pay_for_order'] ) || ! is_checkout_pay_page() ) { 606 return; 607 } 608 609 if ( $this->enabled === 'no' ) { 610 return; 611 } 612 613 $order_key = urldecode( $_GET['key'] ); 614 $order_id = absint( get_query_var( 'order-pay' ) ); 615 616 $order = wc_get_order( $order_id ); 617 618 if ( $this->id !== $order->get_payment_method() ) { 619 return; 620 } 621 622 $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; 623 624 wp_enqueue_script( 'jquery' ); 625 626 wp_enqueue_script( 'credo', 'https://pay.credodemo.com/inline.js', array( 'jquery' ), WC_CREDO_VERSION, false ); 627 628 wp_enqueue_script( 'wc_credo', plugins_url( 'assets/js/credo' . $suffix . '.js', WC_CREDO_MAIN_FILE ), array( 'jquery', 'credo' ), WC_CREDO_VERSION, false ); 629 630 $credo_params = array( 631 'key' => $this->public_key, 632 ); 633 634 if ( is_checkout_pay_page() && get_query_var( 'order-pay' ) ) { 635 636 $email = $order->get_billing_email(); 637 $amount = $order->get_total() * 100; 638 $txnref = $order_id . '_' . time(); 639 $the_order_id = $order->get_id(); 640 $the_order_key = $order->get_order_key(); 641 $currency = $order->get_currency(); 642 643 if ( $the_order_id == $order_id && $the_order_key == $order_key ) { 644 645 $credo_params['email'] = $email; 646 $credo_params['amount'] = $amount; 647 $credo_params['txnref'] = $txnref; 648 $credo_params['currency'] = $currency; 649 650 } 651 652 $credo_params['bearer'] = $this->charges_bearer === 'customer' ? 0 : 1; 653 654 655 if ( $this->split_payment && !empty( $this->service_code ) ) { 656 $credo_params['serviceCode'] = $this->service_code; 657 } 658 659 660 661 if ( $this->custom_metadata ) { 662 663 if ( $this->meta_order_id ) { 664 665 $credo_params['meta_order_id'] = $order_id; 666 667 } 668 669 if ( $this->meta_name ) { 670 671 $credo_params['meta_first_name'] = $order->get_billing_first_name(); 672 $credo_params['meta_last_name'] = $order->get_billing_last_name(); 673 674 675 } 676 677 if ( $this->meta_email ) { 678 679 $credo_params['meta_email'] = $email; 680 681 } 682 683 if ( $this->meta_phone ) { 684 685 $credo_params['meta_phone'] = $order->get_billing_phone(); 686 687 } 688 689 if ( $this->meta_products ) { 690 691 $line_items = $order->get_items(); 692 693 $products = ''; 694 695 foreach ( $line_items as $item_id => $item ) { 696 $name = $item['name']; 697 $quantity = $item['qty']; 698 $products .= $name . ' (Qty: ' . $quantity . ')'; 699 $products .= ' | '; 700 } 701 702 $products = rtrim( $products, ' | ' ); 703 704 $credo_params['meta_products'] = $products; 705 706 } 707 708 if ( $this->meta_billing_address ) { 709 710 $billing_address = $order->get_formatted_billing_address(); 711 $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) ); 712 713 $credo_params['meta_billing_address'] = $billing_address; 714 715 } 716 717 if ( $this->meta_shipping_address ) { 718 719 $shipping_address = $order->get_formatted_shipping_address(); 720 $shipping_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $shipping_address ) ); 721 722 if ( empty( $shipping_address ) ) { 723 724 $billing_address = $order->get_formatted_billing_address(); 725 $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) ); 726 727 $shipping_address = $billing_address; 728 729 } 730 731 $credo_params['meta_shipping_address'] = $shipping_address; 732 733 } 734 } 735 736 $order->update_meta_data( '_credo_txn_ref', $txnref ); 737 $order->save(); 738 } 739 740 wp_localize_script( 'wc_credo', 'wc_credo_params', $credo_params ); 741 742 } 743 744 public function admin_scripts() { 745 746 if ( 'woocommerce_page_wc-settings' !== get_current_screen()->id ) { 747 return; 748 } 749 750 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 751 752 $credo_admin_params = array( 753 'plugin_url' => WC_CREDO_URL, 754 ); 755 756 wp_enqueue_script( 'wc_credo_admin', plugins_url( 'assets/js/credo-admin' . $suffix . '.js', WC_CREDO_MAIN_FILE ), array(), WC_CREDO_VERSION, true ); 757 758 wp_localize_script( 'wc_credo_admin', 'wc_credo_admin_params', $credo_admin_params ); 759 760 } 761 762 /** 763 * Process the payment. 764 * 765 * @param int $order_id 766 * 767 * @return array|void 768 */ 769 public function process_payment( $order_id ) { 770 771 if ( 'redirect' === $this->payment_page ) { 772 773 return $this->process_redirect_payment_option( $order_id ); 774 775 }else { 776 777 $order = wc_get_order($order_id); 778 779 return array( 780 'result' => 'success', 781 'redirect' => $order->get_checkout_payment_url(true), 782 ); 783 } 784 785 } 786 787 /** 788 * Process a redirect payment option payment. 789 * 790 * @param int $order_id 791 * 792 * @return array|void 793 * @since 5.7 794 */ 795 public function process_redirect_payment_option( $order_id ) { 796 797 $order = wc_get_order( $order_id ); 798 $amount = $order->get_total() * 100; 799 $txnref = $order_id . '_' . time(); 800 $callback_url = WC()->api_request_url( 'WC_Gateway_Credo' ); 801 802 $payment_channels = $this->get_gateway_payment_channels( $order ); 803 804 805 $credo_params = array( 806 'amount' => $amount, 807 'email' => $order->get_billing_email(), 808 'currency' => $order->get_currency(), 809 'reference' => $txnref, 810 'callbackUrl' => $callback_url, 811 'customerFirstName' => $order->get_billing_first_name(), 812 'customerLastName' => $order->get_billing_last_name(), 813 'customerPhoneNumber' => $order->get_billing_phone(), 814 815 816 ); 817 818 if ( ! empty( $payment_channels ) ) { 819 $credo_params['channels'] = $payment_channels; 820 } 821 822 $credo_params['bearer'] = $this->charges_bearer === 'customer' ? 0 : 1; 823 824 825 if ( $this->split_payment && !empty( $this->service_code ) ) { 826 $credo_params['serviceCode'] = $this->service_code; 827 } 828 829 $credo_params['metadata']['custom_fields'] = $this->get_custom_fields( $order_id ); 830 $credo_params['metadata']['cancel_action'] = wc_get_cart_url(); 831 832 $order->update_meta_data( '_credo_txn_ref', $txnref ); 833 $order->save(); 834 835 $credo_url = $this->base_url . '/transaction/initialize'; 836 837 $headers = array( 838 'Authorization' => $this->public_key, 839 'Content-Type' => 'application/json', 840 ); 841 842 $args = array( 843 'headers' => $headers, 844 'timeout' => 60, 845 'body' => json_encode( $credo_params ), 846 ); 847 848 $request = wp_remote_post( $credo_url, $args ); 849 850 if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) { 851 852 $credo_response = json_decode( wp_remote_retrieve_body( $request ) ); 853 echo '<script>console.log("PHP error: ' . json_encode( $credo_params ) . '")</script>'; 854 855 return array( 856 'result' => 'success', 857 'redirect' => $credo_response->data->authorizationUrl, 858 ); 859 860 } else { 861 wc_add_notice( __( 'Unable to process payment try again', 'woo-credo' ), 'error' ); 862 863 $credo_response = wp_remote_retrieve_body( $request ); 864 echo '<script>console.log("PHP error: ' . $credo_response . '")</script>'; 865 866 return; 867 } 868 869 } 870 871 872 /** 873 * Show new card can only be added when placing an order notice. 874 */ 875 public function add_payment_method() { 876 877 wc_add_notice( __( 'You can only add a new card when placing an order.', 'woo-credo' ), 'error' ); 878 879 return; 880 881 } 882 883 /** 884 * Displays the payment page. 885 * 886 * @param $order_id 887 */ 888 public function receipt_page( $order_id ) { 889 890 $order = wc_get_order( $order_id ); 891 892 echo '<div id="wc-credo-form">'; 893 894 echo '<p>' . __( 'Thank you for your order, please click the button below to pay with Credo.', 'woo-credo' ) . '</p>'; 895 896 echo '<div id="credo_form"><form id="order_review" method="post" action="' . WC()->api_request_url( 'WC_Gateway_Credo' ) . '"></form><button class="button" id="credo-payment-button">' . __( 'Pay Now', 'woo-credo' ) . '</button>'; 897 898 if ( ! $this->remove_cancel_order_button ) { 899 echo ' <a class="button cancel" id="credo-cancel-payment-button" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order & restore cart', 'woo-credo' ) . '</a></div>'; 900 } 901 902 echo '</div>'; 903 904 } 905 906 /** 907 * Verify Credo payment. 908 */ 909 public function verify_credo_transaction() { 910 911 if ( isset( $_REQUEST['transRef'] ) ) { 912 $credo_txn_ref = sanitize_text_field( $_REQUEST['transRef'] ); 913 } elseif ( isset( $_REQUEST['reference'] ) ) { 914 $credo_txn_ref = sanitize_text_field( $_REQUEST['reference'] ); 915 } else { 916 $credo_txn_ref = false; 917 } 918 919 @ob_clean(); 920 921 if ( $credo_txn_ref ) { 922 923 $credo_response = $this->get_credo_transaction( $credo_txn_ref ); 924 925 if ( false !== $credo_response ) { 926 927 if ( 0 == $credo_response->data->status ) { 928 929 $order_details = explode( '_', $credo_response->data->businessRef ); 930 $order_id = (int) $order_details[0]; 931 $order = wc_get_order( $order_id ); 932 933 if ( in_array( $order->get_status(), array( 'processing', 'completed', 'on-hold' ) ) ) { 934 935 wp_redirect( $this->get_return_url( $order ) ); 936 937 exit; 938 939 } 940 941 $order_total = $order->get_total(); 942 $order_currency = $order->get_currency(); 943 $currency_symbol = get_woocommerce_currency_symbol( $order_currency ); 944 $amount_paid = $credo_response->data->transAmount; 945 $credo_ref = $credo_response->data->transRef; 946 $payment_currency = strtoupper( $credo_response->data->currencyCode ); 947 $gateway_symbol = get_woocommerce_currency_symbol( $payment_currency ); 948 949 // check if the amount paid is equal to the order amount. 950 if ( $amount_paid < $order_total ) { 951 952 $order->update_status( 'on-hold', '' ); 953 954 $order->add_meta_data( '_transaction_id', $credo_ref, true ); 955 956 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment transaction was successful, but the amount paid is not the same as the total order amount.%2$sYour order is currently on hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 957 $notice_type = 'notice'; 958 959 // Add Customer Order Note 960 $order->add_order_note( $notice, 1 ); 961 962 // Add Admin Order Note 963 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Amount paid is less than the total order amount.%3$sAmount Paid was <strong>%4$s (%5$s)</strong> while the total order amount is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $currency_symbol, $amount_paid, $currency_symbol, $order_total, '<br />', $credo_ref ); 964 $order->add_order_note( $admin_order_note ); 965 966 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 967 968 wc_add_notice( $notice, $notice_type ); 969 970 } else { 971 972 if ( $payment_currency !== $order_currency ) { 973 974 $order->update_status( 'on-hold', '' ); 975 976 $order->update_meta_data( '_transaction_id', $credo_ref ); 977 978 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment was successful, but the payment currency is different from the order currency.%2$sYour order is currently on-hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 979 $notice_type = 'notice'; 980 981 // Add Customer Order Note 982 $order->add_order_note( $notice, 1 ); 983 984 // Add Admin Order Note 985 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Order currency is different from the payment currency.%3$sOrder Currency is <strong>%4$s (%5$s)</strong> while the payment currency is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $order_currency, $currency_symbol, $payment_currency, $gateway_symbol, '<br />', $credo_ref ); 986 $order->add_order_note( $admin_order_note ); 987 988 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 989 990 wc_add_notice( $notice, $notice_type ); 991 992 } else { 993 994 $order->payment_complete( $credo_ref ); 995 $order->add_order_note( sprintf( __( 'Payment via Credo successful (Transaction Reference: %s)', 'woo-credo' ), $credo_ref ) ); 996 997 if ( $this->is_autocomplete_order_enabled( $order ) ) { 998 $order->update_status( 'completed' ); 999 } 1000 } 1001 } 1002 1003 $order->save(); 1004 1005 1006 WC()->cart->empty_cart(); 1007 1008 } else { 1009 1010 $order_details = explode( '_', $_REQUEST['reference'] ); 1011 1012 $order_id = (int) $order_details[0]; 1013 1014 $order = wc_get_order( $order_id ); 1015 1016 $order->update_status( 'failed', __( 'Payment was declined by Credo.', 'woo-credo' ) ); 1017 1018 } 1019 } 1020 1021 wp_redirect( $this->get_return_url( $order ) ); 1022 1023 exit; 1024 } 1025 1026 wp_redirect( wc_get_page_permalink( 'cart' ) ); 1027 1028 exit; 1029 1030 } 1031 1032 /** 1033 * Process Webhook. 1034 */ 1035 public function process_webhooks() { 1036 1037 if ( ! array_key_exists( 'HTTP_X_CREDO_SIGNATURE', $_SERVER ) || ( strtoupper( $_SERVER['REQUEST_METHOD'] ) !== 'POST' ) ) { 1038 exit; 1039 } 1040 1041 $json = file_get_contents( 'php://input' ); 1042 1043 // validate event do all at once to avoid timing attack. 1044 if ( $_SERVER['HTTP_X_CREDO_SIGNATURE'] !== hash_hmac( 'sha512', $json, $this->secret_key ) ) { 1045 exit; 1046 } 1047 1048 $event = json_decode( $json ); 1049 1050 if ( 'transaction.success' !== strtolower( $event->event ) ) { 1051 return; 1052 } 1053 1054 sleep( 10 ); 1055 1056 $credo_response = $this->get_credo_transaction( $event->data->transRef ); 1057 1058 if ( false === $credo_response ) { 1059 return; 1060 } 1061 1062 $order_details = explode( '_', $credo_response->data->reference ); 1063 1064 $order_id = (int) $order_details[0]; 1065 1066 $order = wc_get_order( $order_id ); 1067 1068 if ( ! $order ) { 1069 return; 1070 } 1071 1072 $credo_txn_ref = $order->get_meta( '_credo_txn_ref' ); 1073 1074 if ( $credo_response->data->reference != $credo_txn_ref ) { 1075 exit; 1076 } 1077 1078 http_response_code( 200 ); 1079 1080 if ( in_array( strtolower( $order->get_status() ), array( 'processing', 'completed', 'on-hold' ), true ) ) { 1081 exit; 1082 } 1083 1084 $order_currency = $order->get_currency(); 1085 1086 $currency_symbol = get_woocommerce_currency_symbol( $order_currency ); 1087 1088 $order_total = $order->get_total(); 1089 1090 $amount_paid = $credo_response->data->amount / 100; 1091 1092 $credo_ref = $credo_response->data->transRef; 1093 1094 $payment_currency = strtoupper( $credo_response->data->currency ); 1095 1096 $gateway_symbol = get_woocommerce_currency_symbol( $payment_currency ); 1097 1098 // check if the amount paid is equal to the order amount. 1099 if ( $amount_paid < $order_total ) { 1100 1101 $order->update_status( 'on-hold', '' ); 1102 1103 $order->add_meta_data( '_transaction_id', $credo_ref, true ); 1104 1105 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment transaction was successful, but the amount paid is not the same as the total order amount.%2$sYour order is currently on hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 1106 $notice_type = 'notice'; 1107 1108 // Add Customer Order Note. 1109 $order->add_order_note( $notice, 1 ); 1110 1111 // Add Admin Order Note. 1112 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Amount paid is less than the total order amount.%3$sAmount Paid was <strong>%4$s (%5$s)</strong> while the total order amount is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $currency_symbol, $amount_paid, $currency_symbol, $order_total, '<br />', $credo_ref ); 1113 $order->add_order_note( $admin_order_note ); 1114 1115 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 1116 1117 wc_add_notice( $notice, $notice_type ); 1118 1119 WC()->cart->empty_cart(); 1120 1121 } else { 1122 1123 if ( $payment_currency !== $order_currency ) { 1124 1125 $order->update_status( 'on-hold', '' ); 1126 1127 $order->update_meta_data( '_transaction_id', $credo_ref ); 1128 1129 $notice = sprintf( __( 'Thank you for shopping with us.%1$sYour payment was successful, but the payment currency is different from the order currency.%2$sYour order is currently on-hold.%3$sKindly contact us for more information regarding your order and payment status.', 'woo-credo' ), '<br />', '<br />', '<br />' ); 1130 $notice_type = 'notice'; 1131 1132 // Add Customer Order Note. 1133 $order->add_order_note( $notice, 1 ); 1134 1135 // Add Admin Order Note. 1136 $admin_order_note = sprintf( __( '<strong>Look into this order</strong>%1$sThis order is currently on hold.%2$sReason: Order currency is different from the payment currency.%3$sOrder Currency is <strong>%4$s (%5$s)</strong> while the payment currency is <strong>%6$s (%7$s)</strong>%8$s<strong>Credo Transaction Reference:</strong> %9$s', 'woo-credo' ), '<br />', '<br />', '<br />', $order_currency, $currency_symbol, $payment_currency, $gateway_symbol, '<br />', $credo_ref ); 1137 $order->add_order_note( $admin_order_note ); 1138 1139 function_exists( 'wc_reduce_stock_levels' ) ? wc_reduce_stock_levels( $order_id ) : $order->reduce_order_stock(); 1140 1141 wc_add_notice( $notice, $notice_type ); 1142 1143 } else { 1144 1145 $order->payment_complete( $credo_ref ); 1146 1147 $order->add_order_note( sprintf( __( 'Payment via Credo successful (Transaction Reference: %s)', 'woo-credo' ), $credo_ref ) ); 1148 1149 WC()->cart->empty_cart(); 1150 1151 if ( $this->is_autocomplete_order_enabled( $order ) ) { 1152 $order->update_status( 'completed' ); 1153 } 1154 } 1155 } 1156 1157 $order->save(); 1158 1159 1160 exit; 1161 } 1162 1163 1164 /** 1165 * Get custom fields to pass to Credo. 1166 * 1167 * @param int $order_id WC Order ID 1168 * 1169 * @return array 1170 */ 1171 public function get_custom_fields( $order_id ) { 1172 1173 $order = wc_get_order( $order_id ); 1174 1175 $custom_fields = array(); 1176 1177 $custom_fields[] = array( 1178 'display_name' => 'Plugin', 1179 'variable_name' => 'plugin', 1180 'value' => 'woo-credo', 1181 ); 1182 1183 if ( $this->custom_metadata ) { 1184 1185 if ( $this->meta_order_id ) { 1186 1187 $custom_fields[] = array( 1188 'display_name' => 'Order ID', 1189 'variable_name' => 'order_id', 1190 'value' => $order_id, 1191 ); 1192 1193 } 1194 1195 if ( $this->meta_name ) { 1196 1197 $custom_fields[] = array( 1198 'display_name' => 'Customer Name', 1199 'variable_name' => 'customer_name', 1200 'value' => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(), 1201 ); 1202 1203 } 1204 1205 if ( $this->meta_email ) { 1206 1207 $custom_fields[] = array( 1208 'display_name' => 'Customer Email', 1209 'variable_name' => 'customer_email', 1210 'value' => $order->get_billing_email(), 1211 ); 1212 1213 } 1214 1215 if ( $this->meta_phone ) { 1216 1217 $custom_fields[] = array( 1218 'display_name' => 'Customer Phone', 1219 'variable_name' => 'customer_phone', 1220 'value' => $order->get_billing_phone(), 1221 ); 1222 1223 } 1224 1225 if ( $this->meta_products ) { 1226 1227 $line_items = $order->get_items(); 1228 1229 $products = ''; 1230 1231 foreach ( $line_items as $item_id => $item ) { 1232 $name = $item['name']; 1233 $quantity = $item['qty']; 1234 $products .= $name . ' (Qty: ' . $quantity . ')'; 1235 $products .= ' | '; 1236 } 1237 1238 $products = rtrim( $products, ' | ' ); 1239 1240 $custom_fields[] = array( 1241 'display_name' => 'Products', 1242 'variable_name' => 'products', 1243 'value' => $products, 1244 ); 1245 1246 } 1247 1248 if ( $this->meta_billing_address ) { 1249 1250 $billing_address = $order->get_formatted_billing_address(); 1251 $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) ); 1252 1253 $credo_params['meta_billing_address'] = $billing_address; 1254 1255 $custom_fields[] = array( 1256 'display_name' => 'Billing Address', 1257 'variable_name' => 'billing_address', 1258 'value' => $billing_address, 1259 ); 1260 1261 } 1262 1263 if ( $this->meta_shipping_address ) { 1264 1265 $shipping_address = $order->get_formatted_shipping_address(); 1266 $shipping_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $shipping_address ) ); 1267 1268 if ( empty( $shipping_address ) ) { 1269 1270 $billing_address = $order->get_formatted_billing_address(); 1271 $billing_address = esc_html( preg_replace( '#<br\s*/?>#i', ', ', $billing_address ) ); 1272 1273 $shipping_address = $billing_address; 1274 1275 } 1276 $custom_fields[] = array( 1277 'display_name' => 'Shipping Address', 1278 'variable_name' => 'shipping_address', 1279 'value' => $shipping_address, 1280 ); 1281 1282 } 1283 1284 } 1285 1286 return $custom_fields; 1287 } 1288 1289 1290 /** 1291 * Checks if WC version is less than passed in version. 1292 * 1293 * @param string $version Version to check against. 1294 * 1295 * @return bool 1296 */ 1297 public function is_wc_lt( $version ) { 1298 return version_compare( WC_VERSION, $version, '<' ); 1299 } 1300 1301 /** 1302 * Checks if autocomplete order is enabled for the payment method. 1303 * 1304 * @param WC_Order $order Order object. 1305 * 1306 * @return bool 1307 * @since 5.7 1308 */ 1309 protected function is_autocomplete_order_enabled( $order ) { 1310 $autocomplete_order = false; 1311 1312 $payment_method = $order->get_payment_method(); 1313 1314 $credo_settings = get_option( 'woocommerce_' . $payment_method . '_settings' ); 1315 1316 if ( isset( $credo_settings['autocomplete_order'] ) && 'yes' === $credo_settings['autocomplete_order'] ) { 1317 $autocomplete_order = true; 1318 } 1319 1320 return $autocomplete_order; 1321 } 1322 1323 /** 1324 * Retrieve the payment channels configured for the gateway 1325 * 1326 * @param WC_Order $order Order object. 1327 * 1328 * @return array 1329 * @since 5.7 1330 */ 1331 protected function get_gateway_payment_channels( $order ) { 1332 1333 $payment_method = $order->get_payment_method(); 1334 1335 if ( 'credo' === $payment_method ) { 1336 return array(); 1337 } 1338 1339 $payment_channels = $this->payment_channels; 1340 1341 if ( empty( $payment_channels ) ) { 1342 $payment_channels = array( 'card' ); 1343 } 1344 1345 return $payment_channels; 1346 } 1347 1348 /** 1349 * Retrieve a transaction from Credo. 1350 * 1351 * @param $credo_txn_ref 1352 * 1353 * @return false|mixed 1354 * @since 5.7.5 1355 */ 1356 private function get_credo_transaction( $credo_txn_ref ) { 1357 1358 $credo_url = $this->base_url . '/transaction/' . $credo_txn_ref . '/verify'; 1359 1360 $headers = array( 1361 'Authorization' => $this->secret_key, 1362 ); 1363 1364 $args = array( 1365 'headers' => $headers, 1366 'timeout' => 60, 1367 ); 1368 1369 $request = wp_remote_get( $credo_url, $args ); 1370 1371 if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) { 1372 return json_decode( wp_remote_retrieve_body( $request ) ); 1373 } 1374 1375 return false; 1376 } 1246 1377 } -
credo-payment-forms/trunk/readme.txt
r2969965 r2976105 4 4 Requires at least: 5.8 5 5 Tested up to: 6.3 6 Stable tag: 1.0. 66 Stable tag: 1.0.7 7 7 Requires PHP: 7.4 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.txt … … 59 59 3. __Description__ - This controls the message that appears under the payment fields on the checkout page. Use this space to give more details to customers about what Credo is and what payment methods they can use with it. 60 60 4. __Test Mode__ - Check this to enable test mode. When selected, the fields in step six will say "Test" instead of "Live." Test mode enables you to test payments before going live. The orders process with test payment methods, no money is involved so there is no risk. You can uncheck this when your store is ready to accept real payments. 61 5. __Payment Option__ - Select how Credo Checkout displays to your customers. Redirect, is the default. It will redirect your customer to makepayment.61 5. __Payment Option__ - Select how Credo gateway displays to your customers. A popup displays Credo Gateway on the same page, while Redirect will redirect your customer to Credo Gateway page for payment. 62 62 6. __API Keys__ - The next two text boxes are for your Credo API keys, which you can get from your Credo Dashboard. If you enabled Test Mode in step four, then you'll need to use your test API keys here. Otherwise, you can enter your live keys. 63 63 7. __Additional Settings__ - While not necessary for the plugin to function, there are some extra configuration options you have here. You can do things like add custom metadata to your transactions (the data will show up on your Credo dashboard) or use Credo's [Dynamic settlement feature](https://credocentral.com). The tooltips next to the options provide more information on what they do. … … 94 94 * Updated Dynamic Settlement Settings 95 95 96 = 1.0.7 - October 8, 2023 = 97 * Added Pop up payment option 98 96 99 97 100 -
credo-payment-forms/trunk/woo-credo.php
r2969965 r2976105 5 5 * Plugin URI: https://credocentral.com 6 6 * Description: WooCommerce payment gateway for Credo 7 * Version: 1.0. 67 * Version: 1.0.7 8 8 * Author: Lanre Yusuf 9 9 * Author URI: https://linkedin.com/in/lanre-yusuf-a55b3a80 … … 20 20 21 21 if ( ! defined( 'ABSPATH' ) ) { 22 exit;22 exit; 23 23 } 24 24 … … 33 33 function tbz_wc_credo_init() { 34 34 35 load_plugin_textdomain( 'woo-credo', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );35 load_plugin_textdomain( 'woo-credo', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' ); 36 36 37 if ( ! class_exists( 'WC_Payment_Gateway' ) ) {38 add_action( 'admin_notices', 'tbz_wc_credo_wc_missing_notice' );39 return;40 }37 if ( ! class_exists( 'WC_Payment_Gateway' ) ) { 38 add_action( 'admin_notices', 'tbz_wc_credo_wc_missing_notice' ); 39 return; 40 } 41 41 42 add_action( 'admin_init', 'tbz_wc_credo_testmode_notice' );42 add_action( 'admin_init', 'tbz_wc_credo_testmode_notice' ); 43 43 44 require_once dirname( __FILE__ ) . '/includes/class-wc-gateway-credo.php';44 require_once dirname( __FILE__ ) . '/includes/class-wc-gateway-credo.php'; 45 45 46 add_filter( 'woocommerce_payment_gateways', 'tbz_wc_add_credo_gateway', 99 );46 add_filter( 'woocommerce_payment_gateways', 'tbz_wc_add_credo_gateway', 99 ); 47 47 48 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'tbz_woo_credo_plugin_action_links' );48 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'tbz_woo_credo_plugin_action_links' ); 49 49 50 50 } … … 60 60 function tbz_woo_credo_plugin_action_links( $links ) { 61 61 62 $settings_link = array(63 'settings' => '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=credo' ) . '" title="' . __( 'View Credo WooCommerce Settings', 'woo-credo' ) . '">' . __( 'Settings', 'woo-credo' ) . '</a>',64 );62 $settings_link = array( 63 'settings' => '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=credo' ) . '" title="' . __( 'View Credo WooCommerce Settings', 'woo-credo' ) . '">' . __( 'Settings', 'woo-credo' ) . '</a>', 64 ); 65 65 66 return array_merge( $settings_link, $links );66 return array_merge( $settings_link, $links ); 67 67 68 68 } … … 76 76 */ 77 77 function tbz_wc_add_credo_gateway( $methods ) { 78 $methods[] = 'WC_Gateway_Credo';79 return $methods;78 $methods[] = 'WC_Gateway_Credo'; 79 return $methods; 80 80 81 81 } … … 85 85 */ 86 86 function tbz_wc_credo_wc_missing_notice() { 87 echo '<div class="error"><p><strong>' . sprintf( __( 'Credo requires WooCommerce to be installed and active. Click %s to install WooCommerce.', 'woo-credo' ), '<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=woocommerce&TB_iframe=true&width=772&height=539' ) . '" class="thickbox open-plugin-details-modal">here</a>' ) . '</strong></p></div>';87 echo '<div class="error"><p><strong>' . sprintf( __( 'Credo requires WooCommerce to be installed and active. Click %s to install WooCommerce.', 'woo-credo' ), '<a href="' . admin_url( 'plugin-install.php?tab=plugin-information&plugin=woocommerce&TB_iframe=true&width=772&height=539' ) . '" class="thickbox open-plugin-details-modal">here</a>' ) . '</strong></p></div>'; 88 88 } 89 89 … … 93 93 function tbz_wc_credo_testmode_notice() { 94 94 95 if ( ! class_exists( Notes::class ) ) {96 return;97 }95 if ( ! class_exists( Notes::class ) ) { 96 return; 97 } 98 98 99 if ( ! class_exists( WC_Data_Store::class ) ) {100 return;101 }99 if ( ! class_exists( WC_Data_Store::class ) ) { 100 return; 101 } 102 102 103 if ( ! method_exists( Notes::class, 'get_note_by_name' ) ) {104 return;105 }103 if ( ! method_exists( Notes::class, 'get_note_by_name' ) ) { 104 return; 105 } 106 106 107 $test_mode_note = Notes::get_note_by_name( 'credo-test-mode' );107 $test_mode_note = Notes::get_note_by_name( 'credo-test-mode' ); 108 108 109 if ( false !== $test_mode_note ) {110 return;111 }109 if ( false !== $test_mode_note ) { 110 return; 111 } 112 112 113 $credo_settings = get_option( 'woocommerce_credo_settings' );114 $test_mode = isset( $credo_settings['testmode'] ) ? $credo_settings['testmode'] : '';113 $credo_settings = get_option( 'woocommerce_credo_settings' ); 114 $test_mode = isset( $credo_settings['testmode'] ) ? $credo_settings['testmode'] : ''; 115 115 116 if ( 'yes' !== $test_mode ) {117 Notes::delete_notes_with_name( 'credo-test-mode' );116 if ( 'yes' !== $test_mode ) { 117 Notes::delete_notes_with_name( 'credo-test-mode' ); 118 118 119 return;120 }119 return; 120 } 121 121 122 $note = new Note();123 $note->set_title( __( 'Credo test mode enabled', 'woo-credo' ) );124 $note->set_content( __( 'Credo test mode is currently enabled. Remember to disable it when you want to start accepting live payment on your site.', 'woo-credo' ) );125 $note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL );126 $note->set_layout( 'plain' );127 $note->set_is_snoozable( false );128 $note->set_name( 'credo-test-mode' );129 $note->set_source( 'woo-credo' );130 $note->add_action( 'disable-credo-test-mode', __( 'Disable Credo test mode', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=credo' ) );131 $note->save();122 $note = new Note(); 123 $note->set_title( __( 'Credo test mode enabled', 'woo-credo' ) ); 124 $note->set_content( __( 'Credo test mode is currently enabled. Remember to disable it when you want to start accepting live payment on your site.', 'woo-credo' ) ); 125 $note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); 126 $note->set_layout( 'plain' ); 127 $note->set_is_snoozable( false ); 128 $note->set_name( 'credo-test-mode' ); 129 $note->set_source( 'woo-credo' ); 130 $note->add_action( 'disable-credo-test-mode', __( 'Disable Credo test mode', 'woo-credo' ), admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=credo' ) ); 131 $note->save(); 132 132 } 133 133 134 134 add_action( 135 'before_woocommerce_init',136 function () {137 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {138 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );139 }140 }135 'before_woocommerce_init', 136 function () { 137 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { 138 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); 139 } 140 } 141 141 );
Note: See TracChangeset
for help on using the changeset viewer.