Skip to content

Commit

Permalink
feat(core): Allow setting PaymentState on failure to settle Payment
Browse files Browse the repository at this point in the history
Closes #809
  • Loading branch information
michaelbromley committed Apr 7, 2021
1 parent 2dc2fd8 commit 0241ade
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
1 change: 1 addition & 0 deletions packages/core/e2e/fixtures/test-payment-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const failsToSettlePaymentMethod = new PaymentMethodHandler({
settlePayment: () => {
return {
success: false,
state: 'Cancelled',
errorMessage: 'Something went horribly wrong',
metadata: {
privateSettlePaymentData: 'secret',
Expand Down
5 changes: 3 additions & 2 deletions packages/core/e2e/order.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import gql from 'graphql-tag';
import path from 'path';

import { initialData } from '../../../e2e-common/e2e-initial-data';
import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';

import {
failsToSettlePaymentMethod,
Expand Down Expand Up @@ -83,9 +83,9 @@ import {
DELETE_SHIPPING_METHOD,
GET_CUSTOMER_LIST,
GET_ORDER,
GET_ORDERS_LIST,
GET_ORDER_FULFILLMENTS,
GET_ORDER_HISTORY,
GET_ORDERS_LIST,
GET_PRODUCT_WITH_VARIANTS,
GET_STOCK_MOVEMENT,
SETTLE_PAYMENT,
Expand Down Expand Up @@ -356,6 +356,7 @@ describe('Orders resolver', () => {
});

expect(result.order!.state).toBe('PaymentAuthorized');
expect(result.order!.payments![0].state).toBe('Cancelled');
firstOrderCode = order.code;
firstOrderId = order.id;
});
Expand Down
37 changes: 34 additions & 3 deletions packages/core/src/config/payment/payment-method-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export interface CreatePaymentResult {
*
* In a single-step payment flow, this should be set to `'Settled'`.
* In a two-step flow, this should be set to `'Authorized'`.
*
* If using a {@link CustomOrderProcess}, may be something else
* entirely according to your business logic.
*/
state: Exclude<PaymentState, 'Error'>;
/**
Expand Down Expand Up @@ -101,13 +104,41 @@ export interface CreateRefundResult {

/**
* @description
* This object is the return value of the {@link SettlePaymentFn}
* This object is the return value of the {@link SettlePaymentFn} when the Payment
* has been successfully settled.
*
* @docsCategory payment
* @docsPage Payment Method Types
*/
export interface SettlePaymentResult {
success: boolean;
success: true;
metadata?: PaymentMetadata;
}

/**
* @description
* This object is the return value of the {@link SettlePaymentFn} when the Payment
* could not be settled.
*
* @docsCategory payment
* @docsPage Payment Method Types
*/
export interface SettlePaymentErrorResult {
success: false;
/**
* @description
* The state to transition this Payment to upon unsuccessful settlement.
* Defaults to `Error`. Note that if using a different state, it must be
* legal to transition to that state from the `Authorized` state according
* to the PaymentState config (which can be customized using the
* {@link CustomPaymentProcess}).
*/
state?: Exclude<PaymentState, 'Settled'>;
/**
* @description
* The message that will be returned when attempting to settle the payment, and will
* also be persisted as `Payment.errorMessage`.
*/
errorMessage?: string;
metadata?: PaymentMetadata;
}
Expand Down Expand Up @@ -141,7 +172,7 @@ export type SettlePaymentFn<T extends ConfigArgs> = (
order: Order,
payment: Payment,
args: ConfigArgValues<T>,
) => SettlePaymentResult | Promise<SettlePaymentResult>;
) => SettlePaymentResult | SettlePaymentErrorResult | Promise<SettlePaymentResult | SettlePaymentErrorResult>;

/**
* @description
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/service/services/payment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ export class PaymentService {
} else {
payment.errorMessage = settlePaymentResult.errorMessage;
payment.metadata = this.mergePaymentMetadata(payment.metadata, settlePaymentResult.metadata);
await this.paymentStateMachine.transition(
ctx,
payment.order,
payment,
settlePaymentResult.state || 'Error',
);
await this.connection.getRepository(ctx, Payment).save(payment, { reload: false });
}
return payment;
Expand Down

0 comments on commit 0241ade

Please sign in to comment.