mirror of
https://gh.wpcy.net/https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2026-04-25 01:02:18 +08:00
Some checks failed
Build and distribute / build-and-distribute (push) Has been cancelled
CI / PHP 7.4 (push) Has been cancelled
CI / PHP 8.0 (push) Has been cancelled
CI / PHP 8.1 (push) Has been cancelled
CI / PHP 8.2 (push) Has been cancelled
CI / PHP 8.3 (push) Has been cancelled
CI / PHP 8.4 (push) Has been cancelled
PR Playground Demo / prepare_version (push) Has been cancelled
PR Playground Demo / build_plugin (push) Has been cancelled
PR Playground Demo / create_archive (push) Has been cancelled
PR Playground Demo / Comment on PR with Playground details (push) Has been cancelled
213 lines
4.9 KiB
TypeScript
213 lines
4.9 KiB
TypeScript
/**
|
|
* External dependencies
|
|
*/
|
|
import {
|
|
expect,
|
|
RequestUtils,
|
|
WooCommerceApi as WooCommerceApiBase,
|
|
} from '@inpsyde/playwright-utils/build';
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { Pcp } from '../resources';
|
|
import urls from './urls';
|
|
import { generateRandomString } from './helpers';
|
|
|
|
/**
|
|
* Class for REST API interactions with PCP Settings.
|
|
*/
|
|
export class PcpApi extends WooCommerceApiBase {
|
|
requestUtils: RequestUtils;
|
|
|
|
constructor( { request, requestUtils } ) {
|
|
super( { request } );
|
|
this.requestUtils = requestUtils;
|
|
}
|
|
|
|
/**
|
|
* Connects merchant via REST API.
|
|
*
|
|
* @param clientId PayPal merchant's client ID
|
|
* @param clientSecret PayPal merchant's client Isecret
|
|
* @param onboardingOptions
|
|
*/
|
|
connectMerchant = async (
|
|
clientId: string,
|
|
clientSecret: string,
|
|
onboardingOptions: Pcp.Api.OnboardingOptions = {
|
|
isCasualSeller: false,
|
|
products: [ 'physical', 'virtual' ],
|
|
}
|
|
) => {
|
|
// Preset onboarding options
|
|
await this.wcRequest( 'post', 'wc_paypal/onboarding', {
|
|
...onboardingOptions,
|
|
gatewaysRefreshed: true,
|
|
gatewaysSynced: true,
|
|
_locale: 'user',
|
|
} );
|
|
// Merchant connection request
|
|
const response = await this.wcRequest(
|
|
'post',
|
|
'wc_paypal/authenticate/direct',
|
|
{
|
|
clientId,
|
|
clientSecret,
|
|
useSandbox: onboardingOptions?.useSandbox || true,
|
|
_locale: 'user',
|
|
}
|
|
);
|
|
await this.updatePcpSettings( {
|
|
invoicePrefix: `${ generateRandomString( 8 ) }-`,
|
|
} );
|
|
return response;
|
|
};
|
|
|
|
/**
|
|
* Disconnects merchant via REST API with optional DB reset parameter.
|
|
*
|
|
* @param reset
|
|
*/
|
|
disconnectMerchant = async ( reset: boolean = false ) => {
|
|
const response = await this.wcRequest(
|
|
'post',
|
|
'wc_paypal/authenticate/disconnect',
|
|
{
|
|
reset,
|
|
_locale: 'user',
|
|
}
|
|
);
|
|
return response;
|
|
};
|
|
|
|
/**
|
|
* Disconnects merchant with DB reset via REST API.
|
|
*/
|
|
resetDb = () => this.disconnectMerchant( true );
|
|
|
|
/**
|
|
* Updates Payment Methods tab via REST API.
|
|
*
|
|
* @example of data (all params are optional):
|
|
* {
|
|
* fastlaneCardholderName: false,
|
|
* fastlaneDisplayWatermark: true,
|
|
* paypalShowLogo: false,
|
|
* threeDSecure: 'always-3d-secure',
|
|
* "ppcp-gateway": { enabled: true },
|
|
* "pay-later": { enabled: true },
|
|
* }
|
|
*
|
|
* @param data
|
|
*/
|
|
updatePcpPaymentMethods = async ( data: Pcp.Api.PaymentMethods ) => {
|
|
const response = await this.wcRequest( 'post', `wc_paypal/payment`, {
|
|
...data,
|
|
_locale: 'user',
|
|
} );
|
|
return response;
|
|
};
|
|
|
|
/**
|
|
* Updates Settings tab via REST API.
|
|
*
|
|
* @param data
|
|
*/
|
|
updatePcpSettings = async ( data: Pcp.Api.Settings ) => {
|
|
const response = await this.wcRequest( 'post', `wc_paypal/settings`, {
|
|
...data,
|
|
_locale: 'user',
|
|
} );
|
|
return response;
|
|
};
|
|
|
|
isPayPalSubscription( subscription: WooCommerce.Subscription ): boolean {
|
|
return !! subscription?.meta_data?.some(
|
|
( meta ) => meta.key === 'ppcp_subscription'
|
|
);
|
|
}
|
|
|
|
getPayPalSubscriptionBillingId = async ( subscriptionId: number ) => {
|
|
const subscription = await this.getSubscription( subscriptionId );
|
|
|
|
if ( ! subscription ) {
|
|
console.error( `Subscription #${ subscriptionId } was not found.` );
|
|
return 0;
|
|
}
|
|
|
|
const subscriptionMeta = subscription.meta_data.find(
|
|
( meta ) => meta.key === 'ppcp_subscription'
|
|
);
|
|
|
|
return subscriptionMeta.value;
|
|
};
|
|
|
|
/**
|
|
* Get number of Subscription renewals
|
|
*
|
|
* @param subscriptionId
|
|
*/
|
|
getSubscriptionRenewalCount = async ( subscriptionId: number ) => {
|
|
const subscription = await this.getSubscription( subscriptionId );
|
|
const subscriptionMeta = subscription.meta_data.find(
|
|
meta => meta.key === '_subscription_renewal_order_ids_cache'
|
|
);
|
|
return subscriptionMeta?.value?.length ?? 0;
|
|
};
|
|
|
|
/**
|
|
* Triggers PayPal Subscription Renewal process by mocking paypal webhook.
|
|
* Sometimes it is required to send double request, so the retry
|
|
* mechanism is implemented
|
|
*
|
|
* @param subscriptionId
|
|
*/
|
|
triggerPayPalSubscriptionRenewal = async ( subscriptionId: number ) => {
|
|
const initialRenewalCount = await this.getSubscriptionRenewalCount(
|
|
subscriptionId
|
|
);
|
|
|
|
const billingId = await this.getPayPalSubscriptionBillingId(
|
|
subscriptionId
|
|
);
|
|
|
|
const data = {
|
|
id: 'NOT-IMPORTANT',
|
|
event_type: 'PAYMENT.SALE.COMPLETED',
|
|
resource: {
|
|
billing_agreement_id: billingId,
|
|
id: 'NOT-IMPORTANT',
|
|
},
|
|
};
|
|
|
|
let isRenewalTriggered = false;
|
|
let i = 0;
|
|
|
|
while ( ! isRenewalTriggered && i < 2 ) {
|
|
i++;
|
|
|
|
const response = await this.requestUtils.request.post(
|
|
urls.payPalWebhook,
|
|
{ data }
|
|
);
|
|
|
|
expect.soft(
|
|
response.ok(),
|
|
`Assert PayPal Subscription Renewal request (${ i }) to be OK`
|
|
).toBeTruthy();
|
|
|
|
const renewalCount = await this.getSubscriptionRenewalCount(
|
|
subscriptionId
|
|
);
|
|
|
|
isRenewalTriggered = renewalCount === initialRenewalCount + 1;
|
|
}
|
|
|
|
expect.soft(
|
|
isRenewalTriggered,
|
|
'Assert PayPal Subscription Renewal is triggered'
|
|
).toBeTruthy();
|
|
|
|
return isRenewalTriggered;
|
|
};
|
|
}
|