Skip to content

Commit

Permalink
Merge branch 'trunk' into PCP-1393-acdc-save-payment-for-purchase-later
Browse files Browse the repository at this point in the history
  • Loading branch information
Emili Castells Guasch authored and Emili Castells Guasch committed Dec 13, 2023
2 parents 6c3f648 + be28f81 commit fe08948
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 57 deletions.
26 changes: 17 additions & 9 deletions modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PatchCollection;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
Expand Down Expand Up @@ -174,14 +175,15 @@ public function with_bn_code( string $bn_code ): OrderEndpoint {
/**
* Creates an order.
*
* @param PurchaseUnit[] $items The purchase unit items for the order.
* @param string $shipping_preference One of ApplicationContext::SHIPPING_PREFERENCE_ values.
* @param Payer|null $payer The payer off the order.
* @param PaymentToken|null $payment_token The payment token.
* @param string $paypal_request_id The PayPal request id.
* @param string $user_action The user action.
* @param string $payment_method WC payment method.
* @param array $request_data Request data.
* @param PurchaseUnit[] $items The purchase unit items for the order.
* @param string $shipping_preference One of ApplicationContext::SHIPPING_PREFERENCE_ values.
* @param Payer|null $payer The payer off the order.
* @param PaymentToken|null $payment_token The payment token.
* @param string $paypal_request_id The PayPal request id.
* @param string $user_action The user action.
* @param string $payment_method WC payment method.
* @param array $request_data Request data.
* @param PaymentSource|null $payment_source The payment source.
*
* @return Order
* @throws RuntimeException If the request fails.
Expand All @@ -194,7 +196,8 @@ public function create(
string $paypal_request_id = '',
string $user_action = ApplicationContext::USER_ACTION_CONTINUE,
string $payment_method = '',
array $request_data = array()
array $request_data = array(),
PaymentSource $payment_source = null
): Order {
$bearer = $this->bearer->bearer();
$data = array(
Expand All @@ -221,6 +224,11 @@ static function ( PurchaseUnit $item ) use ( $shipping_preference ): array {
if ( $payment_token ) {
$data['payment_source']['token'] = $payment_token->to_array();
}
if ( $payment_source ) {
$data['payment_source'] = array(
$payment_source->name() => $payment_source->properties(),
);
}

/**
* The filter can be used to modify the order creation request body data.
Expand Down
12 changes: 6 additions & 6 deletions modules/ppcp-api-client/src/Entity/PaymentSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ class PaymentSource {
/**
* Payment source properties.
*
* @var stdClass
* @var object
*/
private $properties;

/**
* PaymentSource constructor.
*
* @param string $name Payment source name.
* @param stdClass $properties Payment source properties.
* @param string $name Payment source name.
* @param object $properties Payment source properties.
*/
public function __construct( string $name, stdClass $properties ) {
public function __construct( string $name, object $properties ) {
$this->name = $name;
$this->properties = $properties;
}
Expand All @@ -53,9 +53,9 @@ public function name(): string {
/**
* Payment source properties.
*
* @return stdClass
* @return object
*/
public function properties(): stdClass {
public function properties(): object {
return $this->properties;
}
}
51 changes: 51 additions & 0 deletions modules/ppcp-wc-subscriptions/src/RenewalHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

use WC_Subscription;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
Expand All @@ -21,6 +23,7 @@
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
Expand Down Expand Up @@ -193,6 +196,54 @@ private function process_order( \WC_Order $wc_order ): void {

$token = $this->get_token_for_customer( $customer, $wc_order );
if ( $token ) {
if ( $wc_order->get_payment_method() === CreditCardGateway::ID ) {
$stored_credentials = array(
'payment_initiator' => 'MERCHANT',
'payment_type' => 'RECURRING',
'usage' => 'SUBSEQUENT',
);

$subscriptions = wcs_get_subscriptions_for_renewal_order( $wc_order );
foreach ( $subscriptions as $post_id => $subscription ) {
$previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' );
if ( $previous_transaction_reference ) {
$stored_credentials['previous_transaction_reference'] = $previous_transaction_reference;
break;
}
}

$payment_source = new PaymentSource(
'card',
(object) array(
'vault_id' => $token->id(),
'stored_credential' => $stored_credentials,
)
);

$order = $this->order_endpoint->create(
array( $purchase_unit ),
$shipping_preference,
$payer,
null,
'',
ApplicationContext::USER_ACTION_CONTINUE,
'',
array(),
$payment_source
);

$this->handle_paypal_order( $wc_order, $order );

$this->logger->info(
sprintf(
'Renewal for order %d is completed.',
$wc_order->get_id()
)
);

return;
}

$order = $this->order_endpoint->create(
array( $purchase_unit ),
$shipping_preference,
Expand Down
42 changes: 0 additions & 42 deletions modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,48 +142,6 @@ function ( $default_fields, $id ) use ( $c ) {
20,
2
);

add_filter(
'ppcp_create_order_request_body_data',
function( array $data ) use ( $c ) {
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$wc_order_action = wc_clean( wp_unslash( $_POST['wc_order_action'] ?? '' ) );

// phpcs:ignore WordPress.Security.NonceVerification.Missing
$subscription_id = wc_clean( wp_unslash( $_POST['post_ID'] ?? '' ) );
if ( ! $subscription_id ) {
return $data;
}
$subscription = wc_get_order( $subscription_id );
if ( ! is_a( $subscription, WC_Subscription::class ) ) {
return $data;
}

if (
$wc_order_action === 'wcs_process_renewal' && $subscription->get_payment_method() === CreditCardGateway::ID
&& isset( $data['payment_source']['token'] ) && $data['payment_source']['token']['type'] === 'PAYMENT_METHOD_TOKEN'
&& isset( $data['payment_source']['token']['source']->card )
) {
$data['payment_source'] = array(
'card' => array(
'vault_id' => $data['payment_source']['token']['id'],
'stored_credential' => array(
'payment_initiator' => 'MERCHANT',
'payment_type' => 'RECURRING',
'usage' => 'SUBSEQUENT',
),
),
);

$previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' );
if ( $previous_transaction_reference ) {
$data['payment_source']['card']['stored_credential']['previous_transaction_reference'] = $previous_transaction_reference;
}
}

return $data;
}
);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions tests/PHPUnit/WcSubscriptions/RenewalHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ public function testRenewProcessOrder()
->shouldReceive('payment_source')
->andReturn(null);

$wcOrder
->shouldReceive('get_payment_method')
->andReturn('');
$wcOrder
->shouldReceive('get_meta')
->andReturn('');
Expand Down

0 comments on commit fe08948

Please sign in to comment.