test-payment-methods.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. export const onCancelPaymentSpy = jest.fn();
  21. /**
  22. * A two-stage (authorize, capture) payment method, with no createRefund method.
  23. */
  24. export const twoStagePaymentMethod = new PaymentMethodHandler({
  25. code: 'authorize-only-payment-method',
  26. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  27. args: {},
  28. createPayment: (ctx, order, amount, args, metadata) => {
  29. return {
  30. amount,
  31. state: 'Authorized',
  32. transactionId: '12345-' + order.code,
  33. metadata: { public: metadata },
  34. };
  35. },
  36. settlePayment: () => {
  37. return {
  38. success: true,
  39. metadata: {
  40. moreData: 42,
  41. },
  42. };
  43. },
  44. cancelPayment: (...args) => {
  45. onCancelPaymentSpy(...args);
  46. return {
  47. success: true,
  48. metadata: {
  49. cancellationCode: '12345',
  50. },
  51. };
  52. },
  53. onStateTransitionStart: (fromState, toState, data) => {
  54. onTransitionSpy(fromState, toState, data);
  55. },
  56. });
  57. /**
  58. * A method that can be used to pay for only part of the order (allowing us to test multiple payments
  59. * per order).
  60. */
  61. export const partialPaymentMethod = new PaymentMethodHandler({
  62. code: 'partial-payment-method',
  63. description: [{ languageCode: LanguageCode.en, value: 'Partial Payment Method' }],
  64. args: {},
  65. createPayment: (ctx, order, amount, args, metadata) => {
  66. return {
  67. amount: metadata.amount,
  68. state: metadata.authorizeOnly ? 'Authorized' : 'Settled',
  69. transactionId: '12345',
  70. metadata: { public: metadata },
  71. };
  72. },
  73. settlePayment: () => {
  74. return {
  75. success: true,
  76. };
  77. },
  78. });
  79. /**
  80. * A payment method which includes a createRefund method.
  81. */
  82. export const singleStageRefundablePaymentMethod = new PaymentMethodHandler({
  83. code: 'single-stage-refundable-payment-method',
  84. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  85. args: {},
  86. createPayment: (ctx, order, amount, args, metadata) => {
  87. return {
  88. amount,
  89. state: 'Settled',
  90. transactionId: '12345',
  91. metadata,
  92. };
  93. },
  94. settlePayment: () => {
  95. return { success: true };
  96. },
  97. createRefund: (ctx, input, amount, order, payment, args) => {
  98. return {
  99. state: 'Settled',
  100. transactionId: 'abc123',
  101. };
  102. },
  103. });
  104. let connection: TransactionalConnection;
  105. /**
  106. * A payment method where a Refund attempt will fail the first time
  107. */
  108. export const singleStageRefundFailingPaymentMethod = new PaymentMethodHandler({
  109. code: 'single-stage-refund-failing-payment-method',
  110. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  111. args: {},
  112. init: injector => {
  113. connection = injector.get(TransactionalConnection);
  114. },
  115. createPayment: (ctx, order, amount, args, metadata) => {
  116. return {
  117. amount,
  118. state: 'Settled',
  119. transactionId: '12345',
  120. metadata,
  121. };
  122. },
  123. settlePayment: () => {
  124. return { success: true };
  125. },
  126. createRefund: async (ctx, input, amount, order, payment, args) => {
  127. const paymentWithRefunds = await connection
  128. .getRepository(ctx, Payment)
  129. .findOne(payment.id, { relations: ['refunds'] });
  130. const isFirstRefundAttempt = paymentWithRefunds?.refunds.length === 0;
  131. const metadata = isFirstRefundAttempt ? { errorMessage: 'Service temporarily unavailable' } : {};
  132. return {
  133. state: isFirstRefundAttempt ? 'Failed' : 'Settled',
  134. metadata,
  135. };
  136. },
  137. });
  138. /**
  139. * A payment method where calling `settlePayment` always fails.
  140. */
  141. export const failsToSettlePaymentMethod = new PaymentMethodHandler({
  142. code: 'fails-to-settle-payment-method',
  143. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  144. args: {},
  145. createPayment: (ctx, order, amount, args, metadata) => {
  146. return {
  147. amount,
  148. state: 'Authorized',
  149. transactionId: '12345-' + order.code,
  150. metadata: {
  151. privateCreatePaymentData: 'secret',
  152. public: {
  153. publicCreatePaymentData: 'public',
  154. },
  155. },
  156. };
  157. },
  158. settlePayment: () => {
  159. return {
  160. success: false,
  161. state: 'Cancelled',
  162. errorMessage: 'Something went horribly wrong',
  163. metadata: {
  164. privateSettlePaymentData: 'secret',
  165. public: {
  166. publicSettlePaymentData: 'public',
  167. },
  168. },
  169. };
  170. },
  171. });
  172. /**
  173. * A payment method where calling `settlePayment` always fails.
  174. */
  175. export const failsToCancelPaymentMethod = new PaymentMethodHandler({
  176. code: 'fails-to-cancel-payment-method',
  177. description: [{ languageCode: LanguageCode.en, value: 'Test Payment Method' }],
  178. args: {},
  179. createPayment: (ctx, order, amount, args, metadata) => {
  180. return {
  181. amount,
  182. state: 'Authorized',
  183. transactionId: '12345-' + order.code,
  184. };
  185. },
  186. settlePayment: () => {
  187. return {
  188. success: true,
  189. };
  190. },
  191. cancelPayment: (ctx, order, payment) => {
  192. return {
  193. success: false,
  194. errorMessage: 'something went horribly wrong',
  195. state: payment.state !== 'Cancelled' ? payment.state : undefined,
  196. metadata: {
  197. cancellationData: 'foo',
  198. },
  199. };
  200. },
  201. });
  202. export const testFailingPaymentMethod = new PaymentMethodHandler({
  203. code: 'test-failing-payment-method',
  204. description: [{ languageCode: LanguageCode.en, value: 'Test Failing Payment Method' }],
  205. args: {},
  206. createPayment: (ctx, order, amount, args, metadata) => {
  207. return {
  208. amount,
  209. state: 'Declined',
  210. errorMessage: 'Insufficient funds',
  211. metadata: { public: metadata },
  212. };
  213. },
  214. settlePayment: () => ({
  215. success: true,
  216. }),
  217. });
  218. export const testErrorPaymentMethod = new PaymentMethodHandler({
  219. code: 'test-error-payment-method',
  220. description: [{ languageCode: LanguageCode.en, value: 'Test Error Payment Method' }],
  221. args: {},
  222. createPayment: (ctx, order, amount, args, metadata) => {
  223. return {
  224. amount,
  225. state: 'Error',
  226. errorMessage: 'Something went horribly wrong',
  227. metadata,
  228. };
  229. },
  230. settlePayment: () => ({
  231. success: true,
  232. }),
  233. });