Skip to content

Commit

Permalink
WIP Add support to offline payment methods in checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
gpressutto5 committed Jan 17, 2025
1 parent 17fe404 commit 5a85b90
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
10 changes: 10 additions & 0 deletions includes/class-payment-information.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
exit; // Exit if accessed directly.
}

use WCPay\Constants\Payment_Method;
use WCPay\Constants\Payment_Type;
use WCPay\Constants\Payment_Initiated_By;
use WCPay\Constants\Payment_Capture_Type;
Expand Down Expand Up @@ -498,4 +499,13 @@ public function set_error( \WP_Error $error ) {
public function get_error() {
return $this->error;
}

/**
* Returns true if the payment method is an offline payment method, false otherwise.
*
* @return bool True if the payment method is an offline payment method, false otherwise.
*/
public function is_offline_payment_method(): bool {
return in_array( $this->payment_method_stripe_id, Payment_Method::OFFLINE_PAYMENT_METHODS, true );
}
}
13 changes: 9 additions & 4 deletions includes/class-wc-payment-gateway-wcpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -1786,6 +1786,7 @@ public function process_payment_for_order( $cart, $payment_information, $schedul
$processing = [];
}

$is_offline_payment_method = $payment_information->is_offline_payment_method();
if ( ! empty( $intent ) ) {
if ( ! $intent->is_authorized() ) {
$intent_failed = true;
Expand Down Expand Up @@ -1836,12 +1837,16 @@ public function process_payment_for_order( $cart, $payment_information, $schedul
}

if ( Intent_Status::REQUIRES_ACTION === $status ) {
if ( isset( $next_action['type'] ) && 'redirect_to_url' === $next_action['type'] && ! empty( $next_action['redirect_to_url']['url'] ) ) {
$next_action_type = $next_action['type'] ?? null;
if ( 'redirect_to_url' === $next_action_type && ! empty( $next_action[ $next_action_type ]['url'] ) ) {
$response = [
'result' => 'success',
'redirect' => $next_action['redirect_to_url']['url'],
'redirect' => $next_action[ $next_action_type ]['url'],
];
} elseif ( 'multibanco_display_details' === $next_action_type && ! empty( $next_action[ $next_action_type ]['hosted_voucher_url'] ) ) {
$order->add_meta_data( 'hosted_voucer_url', $next_action[ $next_action_type ]['hosted_voucher_url'], true );
} else {
// If I remove this the modal is not displayed.
$response = [
'result' => 'success',
// Include a new nonce for update_order_status to ensure the update order
Expand All @@ -1862,15 +1867,15 @@ public function process_payment_for_order( $cart, $payment_information, $schedul

$this->order_service->attach_intent_info_to_order( $order, $intent );
$this->attach_exchange_info_to_order( $order, $charge_id );
if ( Intent_Status::SUCCEEDED === $status ) {
if ( Intent_Status::SUCCEEDED === $status || ( Intent_Status::REQUIRES_ACTION === $status && $is_offline_payment_method ) ) {
$this->duplicate_payment_prevention_service->remove_session_processing_order( $order->get_id() );
}
$this->order_service->update_order_status_from_intent( $order, $intent );
$this->order_service->attach_transaction_fee_to_order( $order, $charge );

$this->maybe_add_customer_notification_note( $order, $processing );

if ( isset( $response ) ) {
if ( isset( $response ) && ! $is_offline_payment_method ) {
return $response;
}

Expand Down
31 changes: 30 additions & 1 deletion includes/class-wc-payments-order-service.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use WCPay\Constants\Fraud_Meta_Box_Type;
use WCPay\Constants\Order_Status;
use WCPay\Constants\Intent_Status;
use WCPay\Constants\Payment_Method;
use WCPay\Exceptions\Order_Not_Found_Exception;
use WCPay\Fraud_Prevention\Models\Rule;
use WCPay\Logger;
Expand Down Expand Up @@ -180,7 +181,11 @@ public function update_order_status_from_intent( $order, $intent ) {
break;
case Intent_Status::REQUIRES_ACTION:
case Intent_Status::REQUIRES_PAYMENT_METHOD:
$this->mark_payment_started( $order, $intent_data );
if ( in_array( $intent->get_payment_method_type(), Payment_Method::OFFLINE_PAYMENT_METHODS, true ) ) {
$this->mark_payment_on_hold( $order, $intent_data );
} else {
$this->mark_payment_started( $order, $intent_data );
}
break;
default:
Logger::error( 'Uncaught payment intent status of ' . $intent_data['intent_status'] . ' passed for order id: ' . $order->get_id() );
Expand Down Expand Up @@ -1114,6 +1119,30 @@ private function mark_payment_authorized( $order, $intent_data ) {
$this->set_intention_status_for_order( $order, $intent_data['intent_status'] );
}

/**
* Updates an order to on-hold status, while adding a note with a link to the transaction.
*
* @param WC_Order $order Order object.
* @param array $intent_data The intent data associated with this order.
*
* @return void
*/
private function mark_payment_on_hold( $order, $intent_data ) {
$note = $this->generate_payment_started_note( $order, $intent_data['intent_id'] );
if ( $this->order_note_exists( $order, $note ) ) {
return;
}

if ( Rule::FRAUD_OUTCOME_ALLOW === $intent_data['fraud_outcome'] ) {
$this->set_fraud_outcome_status_for_order( $order, Rule::FRAUD_OUTCOME_ALLOW );
$this->set_fraud_meta_box_type_for_order( $order, Fraud_Meta_Box_Type::ALLOW );
}

$this->update_order_status( $order, Order_Status::ON_HOLD );
$order->add_order_note( $note );
$this->set_intention_status_for_order( $order, $intent_data['intent_status'] );
}

/**
* Updates an order to processing/completed status, while adding a note with a link to the transaction.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/constants/class-payment-method.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,8 @@ class Payment_Method extends Base_Constant {
self::AFTERPAY,
self::KLARNA,
];

const OFFLINE_PAYMENT_METHODS = [
self::MULTIBANCO,
];
}

0 comments on commit 5a85b90

Please sign in to comment.