woocommerce-paypal-payments/tests/qa/utils/paypal-api.ts
Misha Utkin cf436ee149
Fix according to refactored types and resources
- Fix of type declatations
- Fix of data structure
2025-02-06 11:48:52 +01:00

368 lines
8.9 KiB
TypeScript

/**
* External dependencies
*/
import { APIRequestContext, expect } from '@playwright/test';
import { createAuthHeader } from '@inpsyde/playwright-utils/build';
/**
* Internal dependencies
*/
import { Pcp } from '../resources';
/**
* Class for PayPal API
*/
export class PayPalAPI {
request: APIRequestContext;
apiBaseUrl = 'https://api-m.sandbox.paypal.com/v2';
constructor( { request } ) {
this.request = request;
}
private apiRequest = async (
requestType: string,
endPoint: string,
merchant: Pcp.Merchant,
data?: any
) => {
try {
const response = await this.request[ requestType ](
this.apiBaseUrl + endPoint,
{
headers: createAuthHeader(
merchant.client_id,
merchant.client_secret
),
data,
}
);
if ( ! ( await response.ok() ) ) {
throw new Error(
`Request failed with status ${ await response.status() }`
);
}
return await response.json();
} catch ( error ) {
console.error( 'An error occurred:', error );
throw error; // Re-throw the error to propagate it further if needed
}
};
/**
* Gets payment info by PayPal Transaction ID
*
* @param merchant - { client_id: '...', client_secret: '...' }
*/
getToken = async ( merchant: Pcp.Merchant ) => {
const response = await this.request.post(
'https://api.sandbox.paypal.com/v1/oauth2/token',
{
headers: createAuthHeader(
merchant.client_id,
merchant.client_secret
),
form: { grant_type: 'client_credentials' },
}
);
return ( await response.json() ).access_token;
};
/**
* Gets payment info by PayPal Transaction ID
*
* @param resourceId - PayPal transaction ID
* @param merchant - { client_id: '...', client_secret: '...' }
*/
getCapturedPayment = async (
resourceId: string,
merchant: Pcp.Merchant
) => {
return await this.apiRequest(
'get',
`/payments/captures/${ resourceId }`,
merchant
);
};
/**
* Gets payment info for authorized transactions by PayPal Transaction ID
*
* @param resourceId - PayPal transaction ID
* @param merchant - { client_id: '...', client_secret: '...' }
*/
getAuthorizedPayment = async (
resourceId: string,
merchant: Pcp.Merchant
) => {
return await this.apiRequest(
'get',
`/payments/authorizations/${ resourceId }`,
merchant
);
};
/**
* Gets order info by PayPal Order ID
*
* @param resourceId - PayPal order ID
* @param merchant - { client_id: '...', client_secret: '...' }
*/
getOrder = async ( resourceId: string, merchant: Pcp.Merchant ) => {
return await this.apiRequest(
'get',
`/checkout/orders/${ resourceId }`,
merchant
);
};
/**
* Gets order info by PayPal Order ID
*
* @param resourceId - PayPal order ID
* @param merchant - { client_id: '...', client_secret: '...' }
*/
getRefund = async ( resourceId: string, merchant: Pcp.Merchant ) => {
return await this.apiRequest(
'get',
`/payments/refunds/${ resourceId }`,
merchant
);
};
getOrderIdFromWooCommerce = async (
wooCommerceOrderJson: WooCommerce.Order
) => {
return wooCommerceOrderJson.meta_data.filter(
( el ) => el.key === '_ppcp_paypal_order_id'
)[ 0 ].value;
};
/**
* Gets PayPal payment ID for different gateways
*
* @param payPalOrder
* @param payment
*/
getPaymentIdFromOrder = async ( payPalOrder, payment: Pcp.Payment ) => {
const fundingSource = payment.gateway.dataFundingSource;
if ( fundingSource === 'pay_upon_invoice' ) {
return '';
}
if ( fundingSource === 'oxxo' ) {
return payPalOrder.purchase_units[ 0 ].payments.captures[ 0 ].id;
}
if ( payment.isAuthorized ) {
return payPalOrder.purchase_units[ 0 ].payments.authorizations[ 0 ]
.id;
}
return payPalOrder.purchase_units[ 0 ].payments.captures[ 0 ].id;
};
/**
* Gets payment from PayPal API
*
* @param paymentId
* @param shopOrder
*/
getPayment = async (
paymentId: string,
shopOrder: WooCommerce.ShopOrder
) => {
if ( shopOrder.payment.isAuthorized ) {
return await this.getAuthorizedPayment(
paymentId,
shopOrder.merchant
);
}
return await this.getCapturedPayment( paymentId, shopOrder.merchant );
};
/**
*
* @param resourceId
* @param shopOrder
*/
getFee = async ( resourceId: string, shopOrder: WooCommerce.ShopOrder ) => {
const fundingSource = shopOrder.payment.gateway.dataFundingSource;
if (
[ 'pay_upon_invoice', 'oxxo' ].includes( fundingSource ) ||
shopOrder.payment.isAuthorized
) {
return;
}
const payment = await this.getPayment( resourceId, shopOrder );
return payment.seller_receivable_breakdown.paypal_fee.value;
};
getPayout = async (
resourceId: string,
shopOrder: WooCommerce.ShopOrder
) => {
const fundingSource = shopOrder.payment.gateway.dataFundingSource;
if (
[ 'pay_upon_invoice', 'oxxo' ].includes( fundingSource ) ||
shopOrder.payment.isAuthorized
) {
return;
}
const payment = await this.getPayment( resourceId, shopOrder );
return payment.seller_receivable_breakdown.net_amount.value;
};
// Assertions
/**
* Asserts PayPal order for different funding sources
*
* @param wooCommerceOrderJson
* @param shopOrder
*/
assertOrder = async (
wooCommerceOrderJson: WooCommerce.Order,
shopOrder: WooCommerce.ShopOrder
) => {
const fundingSource = shopOrder.payment.gateway.dataFundingSource;
const payPalOrderId = await this.getOrderIdFromWooCommerce(
wooCommerceOrderJson
);
await expect( payPalOrderId ).not.toHaveLength( 0 );
const payPalOrder = await this.getOrder(
payPalOrderId,
shopOrder.merchant
);
if ( fundingSource !== 'oxxo' ) {
const payPalPaymentId = await this.getPaymentIdFromOrder(
payPalOrder,
shopOrder.payment
);
await expect(
String( wooCommerceOrderJson.transaction_id )
).toEqual( String( payPalPaymentId ) );
}
const expectedIntent = shopOrder.payment.isAuthorized
? 'AUTHORIZE'
: 'CAPTURE';
await expect( payPalOrder.intent ).toEqual( expectedIntent );
switch ( fundingSource ) {
case 'oxxo':
await expect( payPalOrder.status ).toEqual( 'COMPLETED' );
await expect( payPalOrder.payment_source ).toHaveProperty(
'oxxo'
);
await expect( payPalOrder.payment_source.oxxo.email ).toEqual(
shopOrder.customer.email
);
break;
case 'acdc':
await expect( payPalOrder.status ).toEqual( 'COMPLETED' );
await expect( payPalOrder.payment_source ).toHaveProperty(
'card'
);
await expect( payPalOrder.payment_source.card.name ).toEqual(
`${ shopOrder.customer.first_name } ${ shopOrder.customer.last_name }`
);
break;
case 'card':
await expect( payPalOrder.status ).toEqual( 'COMPLETED' );
await expect( payPalOrder.payment_source ).toHaveProperty(
'paypal'
);
await expect(
payPalOrder.payment_source.paypal.email_address
).toEqual( shopOrder.customer.email );
await expect(
payPalOrder.payment_source.paypal.name.given_name
).toEqual( shopOrder.customer.first_name );
await expect(
payPalOrder.payment_source.paypal.name.surname
).toEqual( shopOrder.customer.last_name );
break;
case 'pay_upon_invoice':
await expect( payPalOrder.status ).toEqual(
'PENDING_APPROVAL'
);
const birthDate = shopOrder.payment.birthDate.split( '.' );
await expect( payPalOrder.payment_source ).toHaveProperty(
'pay_upon_invoice'
);
await expect(
payPalOrder.payment_source.pay_upon_invoice.birth_date
).toEqual(
`${ birthDate[ 2 ] }-${ birthDate[ 1 ] }-${ birthDate[ 0 ] }`
);
break;
default:
await expect( payPalOrder.status ).toEqual( 'COMPLETED' );
await expect( payPalOrder.payment_source ).toHaveProperty(
'paypal'
);
if ( shopOrder.payment.isVaulted ) {
await expect(
payPalOrder.payment_source.paypal
).toHaveProperty( 'attributes' );
await expect(
payPalOrder.payment_source.paypal.attributes
).toHaveProperty( 'vault' );
await expect(
payPalOrder.payment_source.paypal.attributes.vault
.status
).toEqual( 'VAULTED' );
break;
}
// SIARHEI-TODO fix this:
// if (!(shopOrder.payment.isVaulted==false && shopOrder.payment.method === 'PayPal')) {
await expect(
payPalOrder.payment_source.paypal.email_address
).toEqual( shopOrder.payment.payPalAccount.email );
// break;
// }
}
};
/**
* Asserts PayPal payment
*
* @param paymentId PayPal payment ID
* @param shopOrder
*/
assertPayment = async (
paymentId: string,
shopOrder: WooCommerce.ShopOrder
) => {
const fundingSource = shopOrder.payment.gateway.dataFundingSource;
if ( fundingSource === 'pay_upon_invoice' ) {
return;
}
const payment = await this.getPayment( paymentId, shopOrder );
if ( fundingSource === 'oxxo' ) {
await expect( payment.status ).toEqual( 'PENDING' );
return;
}
if ( shopOrder.payment.isAuthorized ) {
await expect( payment.status ).toEqual( 'CREATED' );
return;
}
await expect( payment.status ).toEqual( 'COMPLETED' );
};
}