test-payment-methods.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { Payment, PaymentMethodHandler, TransactionalConnection } from '@vendure/core';
  2. import { LanguageCode } from '../graphql/generated-e2e-admin-types';
  3. export const testSuccessfulPaymentMethod = new PaymentMethodHandler({
  4. code: 'test-payment-method',
  5. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  6. args: {},
  7. createPayment: (ctx, order, amount, args, metadata) => {
  8. return {
  9. amount,
  10. state: 'Settled',
  11. transactionId: '12345',
  12. metadata: { public: metadata },
  13. };
  14. },
  15. settlePayment: () => ({
  16. success: true,
  17. }),
  18. });
  19. export const onTransitionSpy = jest.fn();
  20. /**
  21. * A two-stage (authorize, capture) payment method, with no createRefund method.
  22. */
  23. export const twoStagePaymentMethod = new PaymentMethodHandler({
  24. code: 'authorize-only-payment-method',
  25. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  26. args: {},
  27. createPayment: (ctx, order, amount, args, metadata) => {
  28. return {
  29. amount,
  30. state: 'Authorized',
  31. transactionId: '12345',
  32. metadata: { public: metadata },
  33. };
  34. },
  35. settlePayment: () => {
  36. return {
  37. success: true,
  38. metadata: {
  39. moreData: 42,
  40. },
  41. };
  42. },
  43. onStateTransitionStart: (fromState, toState, data) => {
  44. onTransitionSpy(fromState, toState, data);
  45. },
  46. });
  47. /**
  48. * A method that can be used to pay for only part of the order (allowing us to test multiple payments
  49. * per order).
  50. */
  51. export const partialPaymentMethod = new PaymentMethodHandler({
  52. code: 'partial-payment-method',
  53. description: [{ languageCode: LanguageCode.en, value: 'Partial Payment Method' }],
  54. args: {},
  55. createPayment: (ctx, order, amount, args, metadata) => {
  56. return {
  57. amount: metadata.amount,
  58. state: metadata.authorizeOnly ? 'Authorized' : 'Settled',
  59. transactionId: '12345',
  60. metadata: { public: metadata },
  61. };
  62. },
  63. settlePayment: () => {
  64. return {
  65. success: true,
  66. };
  67. },
  68. });
  69. /**
  70. * A payment method which includes a createRefund method.
  71. */
  72. export const singleStageRefundablePaymentMethod = new PaymentMethodHandler({
  73. code: 'single-stage-refundable-payment-method',
  74. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  75. args: {},
  76. createPayment: (ctx, order, amount, args, metadata) => {
  77. return {
  78. amount,
  79. state: 'Settled',
  80. transactionId: '12345',
  81. metadata,
  82. };
  83. },
  84. settlePayment: () => {
  85. return { success: true };
  86. },
  87. createRefund: (ctx, input, amount, order, payment, args) => {
  88. return {
  89. state: 'Settled',
  90. transactionId: 'abc123',
  91. };
  92. },
  93. });
  94. let connection: TransactionalConnection;
  95. /**
  96. * A payment method where a Refund attempt will fail the first time
  97. */
  98. export const singleStageRefundFailingPaymentMethod = new PaymentMethodHandler({
  99. code: 'single-stage-refund-failing-payment-method',
  100. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  101. args: {},
  102. init: injector => {
  103. connection = injector.get(TransactionalConnection);
  104. },
  105. createPayment: (ctx, order, amount, args, metadata) => {
  106. return {
  107. amount,
  108. state: 'Settled',
  109. transactionId: '12345',
  110. metadata,
  111. };
  112. },
  113. settlePayment: () => {
  114. return { success: true };
  115. },
  116. createRefund: async (ctx, input, amount, order, payment, args) => {
  117. const paymentWithRefunds = await connection
  118. .getRepository(ctx, Payment)
  119. .findOne(payment.id, { relations: ['refunds'] });
  120. const isFirstRefundAttempt = paymentWithRefunds?.refunds.length === 0;
  121. const metadata = isFirstRefundAttempt ? { errorMessage: 'Service temporarily unavailable' } : {};
  122. return {
  123. state: isFirstRefundAttempt ? 'Failed' : 'Settled',
  124. metadata,
  125. };
  126. },
  127. });
  128. /**
  129. * A payment method where calling `settlePayment` always fails.
  130. */
  131. export const failsToSettlePaymentMethod = new PaymentMethodHandler({
  132. code: 'fails-to-settle-payment-method',
  133. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  134. args: {},
  135. createPayment: (ctx, order, amount, args, metadata) => {
  136. return {
  137. amount,
  138. state: 'Authorized',
  139. transactionId: '12345',
  140. metadata: {
  141. privateCreatePaymentData: 'secret',
  142. public: {
  143. publicCreatePaymentData: 'public',
  144. },
  145. },
  146. };
  147. },
  148. settlePayment: () => {
  149. return {
  150. success: false,
  151. state: 'Cancelled',
  152. errorMessage: 'Something went horribly wrong',
  153. metadata: {
  154. privateSettlePaymentData: 'secret',
  155. public: {
  156. publicSettlePaymentData: 'public',
  157. },
  158. },
  159. };
  160. },
  161. });
  162. export const testFailingPaymentMethod = new PaymentMethodHandler({
  163. code: 'test-failing-payment-method',
  164. description: [{ languageCode: LanguageCode.en, value: 'Test Failing Payment Method' }],
  165. args: {},
  166. createPayment: (ctx, order, amount, args, metadata) => {
  167. return {
  168. amount,
  169. state: 'Declined',
  170. errorMessage: 'Insufficient funds',
  171. metadata: { public: metadata },
  172. };
  173. },
  174. settlePayment: () => ({
  175. success: true,
  176. }),
  177. });
  178. export const testErrorPaymentMethod = new PaymentMethodHandler({
  179. code: 'test-error-payment-method',
  180. description: [{ languageCode: LanguageCode.en, value: 'Test Error Payment Method' }],
  181. args: {},
  182. createPayment: (ctx, order, amount, args, metadata) => {
  183. return {
  184. amount,
  185. state: 'Error',
  186. errorMessage: 'Something went horribly wrong',
  187. metadata,
  188. };
  189. },
  190. settlePayment: () => ({
  191. success: true,
  192. }),
  193. });