payment-method.e2e-spec.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /* eslint-disable @typescript-eslint/no-non-null-assertion */
  2. import {
  3. DefaultLogger,
  4. dummyPaymentHandler,
  5. LanguageCode,
  6. PaymentMethodEligibilityChecker,
  7. } from '@vendure/core';
  8. import {
  9. createErrorResultGuard,
  10. createTestEnvironment,
  11. E2E_DEFAULT_CHANNEL_TOKEN,
  12. ErrorResultGuard,
  13. } from '@vendure/testing';
  14. import gql from 'graphql-tag';
  15. import path from 'path';
  16. import { vi } from 'vitest';
  17. import { afterAll, beforeAll, describe, expect, it } from 'vitest';
  18. import { initialData } from '../../../e2e-common/e2e-initial-data';
  19. import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
  20. import { CurrencyCode, DeletionResult } from './graphql/generated-e2e-admin-types';
  21. import * as Codegen from './graphql/generated-e2e-admin-types';
  22. import { ErrorCode } from './graphql/generated-e2e-shop-types';
  23. import * as CodegenShop from './graphql/generated-e2e-shop-types';
  24. import { CREATE_CHANNEL } from './graphql/shared-definitions';
  25. import {
  26. ACTIVE_PAYMENT_METHODS_QUERY,
  27. ADD_ITEM_TO_ORDER,
  28. ADD_PAYMENT,
  29. GET_ELIGIBLE_PAYMENT_METHODS,
  30. } from './graphql/shop-definitions';
  31. import { proceedToArrangingPayment } from './utils/test-order-utils';
  32. const checkerSpy = vi.fn();
  33. const minPriceChecker = new PaymentMethodEligibilityChecker({
  34. code: 'min-price-checker',
  35. description: [{ languageCode: LanguageCode.en, value: 'Min price checker' }],
  36. args: {
  37. minPrice: {
  38. type: 'int',
  39. },
  40. },
  41. check(ctx, order, args) {
  42. checkerSpy();
  43. if (order.totalWithTax >= args.minPrice) {
  44. return true;
  45. } else {
  46. return 'Order total too low';
  47. }
  48. },
  49. });
  50. describe('PaymentMethod resolver', () => {
  51. const orderGuard: ErrorResultGuard<CodegenShop.TestOrderWithPaymentsFragment> = createErrorResultGuard(
  52. input => !!input.lines,
  53. );
  54. const { server, adminClient, shopClient } = createTestEnvironment({
  55. ...testConfig(),
  56. // logger: new DefaultLogger(),
  57. paymentOptions: {
  58. paymentMethodEligibilityCheckers: [minPriceChecker],
  59. paymentMethodHandlers: [dummyPaymentHandler],
  60. },
  61. });
  62. beforeAll(async () => {
  63. await server.init({
  64. initialData,
  65. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
  66. customerCount: 2,
  67. });
  68. await adminClient.asSuperAdmin();
  69. }, TEST_SETUP_TIMEOUT_MS);
  70. afterAll(async () => {
  71. await server.destroy();
  72. });
  73. it('create', async () => {
  74. const { createPaymentMethod } = await adminClient.query<
  75. Codegen.CreatePaymentMethodMutation,
  76. Codegen.CreatePaymentMethodMutationVariables
  77. >(CREATE_PAYMENT_METHOD, {
  78. input: {
  79. code: 'no-checks',
  80. enabled: true,
  81. handler: {
  82. code: dummyPaymentHandler.code,
  83. arguments: [{ name: 'automaticSettle', value: 'true' }],
  84. },
  85. translations: [
  86. {
  87. languageCode: LanguageCode.en,
  88. name: 'No Checker',
  89. description: 'This is a test payment method',
  90. },
  91. ],
  92. },
  93. });
  94. expect(createPaymentMethod).toEqual({
  95. id: 'T_1',
  96. name: 'No Checker',
  97. code: 'no-checks',
  98. description: 'This is a test payment method',
  99. enabled: true,
  100. checker: null,
  101. handler: {
  102. args: [
  103. {
  104. name: 'automaticSettle',
  105. value: 'true',
  106. },
  107. ],
  108. code: 'dummy-payment-handler',
  109. },
  110. translations: [
  111. {
  112. description: 'This is a test payment method',
  113. id: 'T_1',
  114. languageCode: 'en',
  115. name: 'No Checker',
  116. },
  117. ],
  118. });
  119. });
  120. it('update', async () => {
  121. const { updatePaymentMethod } = await adminClient.query<
  122. Codegen.UpdatePaymentMethodMutation,
  123. Codegen.UpdatePaymentMethodMutationVariables
  124. >(UPDATE_PAYMENT_METHOD, {
  125. input: {
  126. id: 'T_1',
  127. checker: {
  128. code: minPriceChecker.code,
  129. arguments: [{ name: 'minPrice', value: '0' }],
  130. },
  131. handler: {
  132. code: dummyPaymentHandler.code,
  133. arguments: [{ name: 'automaticSettle', value: 'false' }],
  134. },
  135. translations: [
  136. {
  137. languageCode: LanguageCode.en,
  138. description: 'modified',
  139. },
  140. ],
  141. },
  142. });
  143. expect(updatePaymentMethod).toEqual({
  144. id: 'T_1',
  145. name: 'No Checker',
  146. code: 'no-checks',
  147. description: 'modified',
  148. enabled: true,
  149. checker: {
  150. args: [{ name: 'minPrice', value: '0' }],
  151. code: minPriceChecker.code,
  152. },
  153. handler: {
  154. args: [
  155. {
  156. name: 'automaticSettle',
  157. value: 'false',
  158. },
  159. ],
  160. code: dummyPaymentHandler.code,
  161. },
  162. translations: [
  163. {
  164. description: 'modified',
  165. id: 'T_1',
  166. languageCode: 'en',
  167. name: 'No Checker',
  168. },
  169. ],
  170. });
  171. });
  172. it('unset checker', async () => {
  173. const { updatePaymentMethod } = await adminClient.query<
  174. Codegen.UpdatePaymentMethodMutation,
  175. Codegen.UpdatePaymentMethodMutationVariables
  176. >(UPDATE_PAYMENT_METHOD, {
  177. input: {
  178. id: 'T_1',
  179. checker: null,
  180. },
  181. });
  182. expect(updatePaymentMethod.checker).toEqual(null);
  183. const { paymentMethod } = await adminClient.query<
  184. Codegen.GetPaymentMethodQuery,
  185. Codegen.GetPaymentMethodQueryVariables
  186. >(GET_PAYMENT_METHOD, { id: 'T_1' });
  187. expect(paymentMethod!.checker).toEqual(null);
  188. });
  189. it('paymentMethodEligibilityCheckers', async () => {
  190. const { paymentMethodEligibilityCheckers } =
  191. await adminClient.query<Codegen.GetPaymentMethodCheckersQuery>(GET_PAYMENT_METHOD_CHECKERS);
  192. expect(paymentMethodEligibilityCheckers).toEqual([
  193. {
  194. code: minPriceChecker.code,
  195. args: [{ name: 'minPrice', type: 'int' }],
  196. },
  197. ]);
  198. });
  199. it('paymentMethodHandlers', async () => {
  200. const { paymentMethodHandlers } =
  201. await adminClient.query<Codegen.GetPaymentMethodHandlersQuery>(GET_PAYMENT_METHOD_HANDLERS);
  202. expect(paymentMethodHandlers).toEqual([
  203. {
  204. code: dummyPaymentHandler.code,
  205. args: [{ name: 'automaticSettle', type: 'boolean' }],
  206. },
  207. ]);
  208. });
  209. describe('eligibility checks', () => {
  210. beforeAll(async () => {
  211. await adminClient.query<
  212. Codegen.CreatePaymentMethodMutation,
  213. Codegen.CreatePaymentMethodMutationVariables
  214. >(CREATE_PAYMENT_METHOD, {
  215. input: {
  216. code: 'price-check',
  217. enabled: true,
  218. checker: {
  219. code: minPriceChecker.code,
  220. arguments: [{ name: 'minPrice', value: '200000' }],
  221. },
  222. handler: {
  223. code: dummyPaymentHandler.code,
  224. arguments: [{ name: 'automaticSettle', value: 'true' }],
  225. },
  226. translations: [
  227. {
  228. languageCode: LanguageCode.en,
  229. name: 'With Min Price Checker',
  230. description: 'Order total must be more than 2k',
  231. },
  232. ],
  233. },
  234. });
  235. await adminClient.query<
  236. Codegen.CreatePaymentMethodMutation,
  237. Codegen.CreatePaymentMethodMutationVariables
  238. >(CREATE_PAYMENT_METHOD, {
  239. input: {
  240. code: 'disabled-method',
  241. enabled: false,
  242. handler: {
  243. code: dummyPaymentHandler.code,
  244. arguments: [{ name: 'automaticSettle', value: 'true' }],
  245. },
  246. translations: [
  247. {
  248. languageCode: LanguageCode.en,
  249. name: 'Disabled ones',
  250. description: 'This method is disabled',
  251. },
  252. ],
  253. },
  254. });
  255. await shopClient.asUserWithCredentials('hayden.zieme12@hotmail.com', 'test');
  256. await shopClient.query<
  257. CodegenShop.AddItemToOrderMutation,
  258. CodegenShop.AddItemToOrderMutationVariables
  259. >(ADD_ITEM_TO_ORDER, {
  260. productVariantId: 'T_1',
  261. quantity: 1,
  262. });
  263. await proceedToArrangingPayment(shopClient);
  264. });
  265. it('eligiblePaymentMethods', async () => {
  266. const { eligiblePaymentMethods } =
  267. await shopClient.query<CodegenShop.GetEligiblePaymentMethodsQuery>(
  268. GET_ELIGIBLE_PAYMENT_METHODS,
  269. );
  270. expect(eligiblePaymentMethods).toEqual([
  271. {
  272. id: 'T_1',
  273. code: 'no-checks',
  274. isEligible: true,
  275. eligibilityMessage: null,
  276. },
  277. {
  278. id: 'T_2',
  279. code: 'price-check',
  280. isEligible: false,
  281. eligibilityMessage: 'Order total too low',
  282. },
  283. ]);
  284. });
  285. it('addPaymentToOrder does not allow ineligible method', async () => {
  286. checkerSpy.mockClear();
  287. const { addPaymentToOrder } = await shopClient.query<
  288. CodegenShop.AddPaymentToOrderMutation,
  289. CodegenShop.AddPaymentToOrderMutationVariables
  290. >(ADD_PAYMENT, {
  291. input: {
  292. method: 'price-check',
  293. metadata: {},
  294. },
  295. });
  296. orderGuard.assertErrorResult(addPaymentToOrder);
  297. expect(addPaymentToOrder.errorCode).toBe(ErrorCode.INELIGIBLE_PAYMENT_METHOD_ERROR);
  298. expect(addPaymentToOrder.eligibilityCheckerMessage).toBe('Order total too low');
  299. expect(checkerSpy).toHaveBeenCalledTimes(1);
  300. });
  301. });
  302. describe('channels', () => {
  303. const SECOND_CHANNEL_TOKEN = 'SECOND_CHANNEL_TOKEN';
  304. const THIRD_CHANNEL_TOKEN = 'THIRD_CHANNEL_TOKEN';
  305. beforeAll(async () => {
  306. await adminClient.query<Codegen.CreateChannelMutation, Codegen.CreateChannelMutationVariables>(
  307. CREATE_CHANNEL,
  308. {
  309. input: {
  310. code: 'second-channel',
  311. token: SECOND_CHANNEL_TOKEN,
  312. defaultLanguageCode: LanguageCode.en,
  313. currencyCode: CurrencyCode.GBP,
  314. pricesIncludeTax: true,
  315. defaultShippingZoneId: 'T_1',
  316. defaultTaxZoneId: 'T_1',
  317. },
  318. },
  319. );
  320. await adminClient.query<Codegen.CreateChannelMutation, Codegen.CreateChannelMutationVariables>(
  321. CREATE_CHANNEL,
  322. {
  323. input: {
  324. code: 'third-channel',
  325. token: THIRD_CHANNEL_TOKEN,
  326. defaultLanguageCode: LanguageCode.en,
  327. currencyCode: CurrencyCode.GBP,
  328. pricesIncludeTax: true,
  329. defaultShippingZoneId: 'T_1',
  330. defaultTaxZoneId: 'T_1',
  331. },
  332. },
  333. );
  334. });
  335. it('creates a PaymentMethod in channel2', async () => {
  336. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  337. const { createPaymentMethod } = await adminClient.query<
  338. Codegen.CreatePaymentMethodMutation,
  339. Codegen.CreatePaymentMethodMutationVariables
  340. >(CREATE_PAYMENT_METHOD, {
  341. input: {
  342. code: 'channel-2-method',
  343. enabled: true,
  344. handler: {
  345. code: dummyPaymentHandler.code,
  346. arguments: [{ name: 'automaticSettle', value: 'true' }],
  347. },
  348. translations: [
  349. {
  350. languageCode: LanguageCode.en,
  351. name: 'Channel 2 method',
  352. description: 'This is a test payment method',
  353. },
  354. ],
  355. },
  356. });
  357. expect(createPaymentMethod.code).toBe('channel-2-method');
  358. });
  359. it('method is listed in channel2', async () => {
  360. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  361. const { paymentMethods } =
  362. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  363. expect(paymentMethods.totalItems).toBe(1);
  364. expect(paymentMethods.items[0].code).toBe('channel-2-method');
  365. });
  366. it('method is not listed in channel3', async () => {
  367. adminClient.setChannelToken(THIRD_CHANNEL_TOKEN);
  368. const { paymentMethods } =
  369. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  370. expect(paymentMethods.totalItems).toBe(0);
  371. });
  372. it('method is listed in default channel', async () => {
  373. adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
  374. const { paymentMethods } =
  375. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  376. expect(paymentMethods.totalItems).toBe(4);
  377. expect(paymentMethods.items.map(i => i.code).sort()).toEqual([
  378. 'channel-2-method',
  379. 'disabled-method',
  380. 'no-checks',
  381. 'price-check',
  382. ]);
  383. });
  384. it('delete from channel', async () => {
  385. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  386. const { paymentMethods } =
  387. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  388. expect(paymentMethods.totalItems).toBe(1);
  389. const { deletePaymentMethod } = await adminClient.query<
  390. Codegen.DeletePaymentMethodMutation,
  391. Codegen.DeletePaymentMethodMutationVariables
  392. >(DELETE_PAYMENT_METHOD, {
  393. id: paymentMethods.items[0].id,
  394. });
  395. expect(deletePaymentMethod.result).toBe(DeletionResult.DELETED);
  396. const { paymentMethods: checkChannel } =
  397. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  398. expect(checkChannel.totalItems).toBe(0);
  399. adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
  400. const { paymentMethods: checkDefault } =
  401. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  402. expect(checkDefault.totalItems).toBe(4);
  403. });
  404. it('delete from default channel', async () => {
  405. adminClient.setChannelToken(SECOND_CHANNEL_TOKEN);
  406. const { createPaymentMethod } = await adminClient.query<
  407. Codegen.CreatePaymentMethodMutation,
  408. Codegen.CreatePaymentMethodMutationVariables
  409. >(CREATE_PAYMENT_METHOD, {
  410. input: {
  411. code: 'channel-2-method2',
  412. enabled: true,
  413. handler: {
  414. code: dummyPaymentHandler.code,
  415. arguments: [{ name: 'automaticSettle', value: 'true' }],
  416. },
  417. translations: [
  418. {
  419. languageCode: LanguageCode.en,
  420. name: 'Channel 2 method 2',
  421. description: 'This is a test payment method',
  422. },
  423. ],
  424. },
  425. });
  426. adminClient.setChannelToken(E2E_DEFAULT_CHANNEL_TOKEN);
  427. const { deletePaymentMethod: delete1 } = await adminClient.query<
  428. Codegen.DeletePaymentMethodMutation,
  429. Codegen.DeletePaymentMethodMutationVariables
  430. >(DELETE_PAYMENT_METHOD, {
  431. id: createPaymentMethod.id,
  432. });
  433. expect(delete1.result).toBe(DeletionResult.NOT_DELETED);
  434. expect(delete1.message).toBe(
  435. 'The selected PaymentMethod is assigned to the following Channels: second-channel. Set "force: true" to delete from all Channels.',
  436. );
  437. const { paymentMethods: check1 } =
  438. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  439. expect(check1.totalItems).toBe(5);
  440. const { deletePaymentMethod: delete2 } = await adminClient.query<
  441. Codegen.DeletePaymentMethodMutation,
  442. Codegen.DeletePaymentMethodMutationVariables
  443. >(DELETE_PAYMENT_METHOD, {
  444. id: createPaymentMethod.id,
  445. force: true,
  446. });
  447. expect(delete2.result).toBe(DeletionResult.DELETED);
  448. const { paymentMethods: check2 } =
  449. await adminClient.query<Codegen.GetPaymentMethodListQuery>(GET_PAYMENT_METHOD_LIST);
  450. expect(check2.totalItems).toBe(4);
  451. });
  452. });
  453. it('create without description', async () => {
  454. const { createPaymentMethod } = await adminClient.query<
  455. Codegen.CreatePaymentMethodMutation,
  456. Codegen.CreatePaymentMethodMutationVariables
  457. >(CREATE_PAYMENT_METHOD, {
  458. input: {
  459. code: 'no-description',
  460. enabled: true,
  461. handler: {
  462. code: dummyPaymentHandler.code,
  463. arguments: [{ name: 'automaticSettle', value: 'true' }],
  464. },
  465. translations: [
  466. {
  467. languageCode: LanguageCode.en,
  468. name: 'No Description',
  469. },
  470. ],
  471. },
  472. });
  473. expect(createPaymentMethod).toEqual({
  474. id: 'T_6',
  475. name: 'No Description',
  476. code: 'no-description',
  477. description: '',
  478. enabled: true,
  479. checker: null,
  480. handler: {
  481. args: [
  482. {
  483. name: 'automaticSettle',
  484. value: 'true',
  485. },
  486. ],
  487. code: 'dummy-payment-handler',
  488. },
  489. translations: [
  490. {
  491. description: '',
  492. id: 'T_6',
  493. languageCode: 'en',
  494. name: 'No Description',
  495. },
  496. ],
  497. });
  498. });
  499. it('returns only active payment methods', async () => {
  500. // Cleanup: Remove all existing payment methods
  501. const { paymentMethods } = await adminClient.query(GET_PAYMENT_METHOD_LIST);
  502. for (const method of paymentMethods.items) {
  503. await adminClient.query(DELETE_PAYMENT_METHOD, { id: method.id, force: true });
  504. }
  505. // Arrange: Create both enabled and disabled payment methods
  506. await adminClient.query(CREATE_PAYMENT_METHOD, {
  507. input: {
  508. code: 'active-method',
  509. enabled: true,
  510. handler: {
  511. code: 'dummy-payment-handler',
  512. arguments: [{ name: 'automaticSettle', value: 'true' }],
  513. },
  514. translations: [
  515. {
  516. languageCode: LanguageCode.en,
  517. name: 'Active Method',
  518. description: 'This is an active method',
  519. },
  520. ],
  521. },
  522. });
  523. await adminClient.query(CREATE_PAYMENT_METHOD, {
  524. input: {
  525. code: 'inactive-method',
  526. enabled: false,
  527. handler: {
  528. code: 'dummy-payment-handler',
  529. arguments: [{ name: 'automaticSettle', value: 'true' }],
  530. },
  531. translations: [
  532. {
  533. languageCode: LanguageCode.en,
  534. name: 'Inactive Method',
  535. description: 'This is an inactive method',
  536. },
  537. ],
  538. },
  539. });
  540. // Act: Query active payment methods
  541. const { activePaymentMethods } = await shopClient.query(ACTIVE_PAYMENT_METHODS_QUERY);
  542. // Assert: Ensure only the active payment method is returned
  543. expect(activePaymentMethods).toHaveLength(1);
  544. expect(activePaymentMethods[0].code).toBe('active-method');
  545. expect(activePaymentMethods[0].name).toBe('Active Method');
  546. expect(activePaymentMethods[0].description).toBe('This is an active method');
  547. });
  548. });
  549. export const PAYMENT_METHOD_FRAGMENT = gql`
  550. fragment PaymentMethod on PaymentMethod {
  551. id
  552. code
  553. name
  554. description
  555. enabled
  556. checker {
  557. code
  558. args {
  559. name
  560. value
  561. }
  562. }
  563. handler {
  564. code
  565. args {
  566. name
  567. value
  568. }
  569. }
  570. translations {
  571. id
  572. languageCode
  573. name
  574. description
  575. }
  576. }
  577. `;
  578. export const CREATE_PAYMENT_METHOD = gql`
  579. mutation CreatePaymentMethod($input: CreatePaymentMethodInput!) {
  580. createPaymentMethod(input: $input) {
  581. ...PaymentMethod
  582. }
  583. }
  584. ${PAYMENT_METHOD_FRAGMENT}
  585. `;
  586. export const UPDATE_PAYMENT_METHOD = gql`
  587. mutation UpdatePaymentMethod($input: UpdatePaymentMethodInput!) {
  588. updatePaymentMethod(input: $input) {
  589. ...PaymentMethod
  590. }
  591. }
  592. ${PAYMENT_METHOD_FRAGMENT}
  593. `;
  594. export const GET_PAYMENT_METHOD_HANDLERS = gql`
  595. query GetPaymentMethodHandlers {
  596. paymentMethodHandlers {
  597. code
  598. args {
  599. name
  600. type
  601. }
  602. }
  603. }
  604. `;
  605. export const GET_PAYMENT_METHOD_CHECKERS = gql`
  606. query GetPaymentMethodCheckers {
  607. paymentMethodEligibilityCheckers {
  608. code
  609. args {
  610. name
  611. type
  612. }
  613. }
  614. }
  615. `;
  616. export const GET_PAYMENT_METHOD = gql`
  617. query GetPaymentMethod($id: ID!) {
  618. paymentMethod(id: $id) {
  619. ...PaymentMethod
  620. }
  621. }
  622. ${PAYMENT_METHOD_FRAGMENT}
  623. `;
  624. export const GET_PAYMENT_METHOD_LIST = gql`
  625. query GetPaymentMethodList($options: PaymentMethodListOptions) {
  626. paymentMethods(options: $options) {
  627. items {
  628. ...PaymentMethod
  629. }
  630. totalItems
  631. }
  632. }
  633. ${PAYMENT_METHOD_FRAGMENT}
  634. `;
  635. export const DELETE_PAYMENT_METHOD = gql`
  636. mutation DeletePaymentMethod($id: ID!, $force: Boolean) {
  637. deletePaymentMethod(id: $id, force: $force) {
  638. message
  639. result
  640. }
  641. }
  642. `;