@graphcommerce/magento-cart-payment-method 2.105.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/Api/AvailablePaymentMethod/AvailablePaymentMethod.gql.ts +4 -0
  2. package/Api/AvailablePaymentMethod/AvailablePaymentMethod.graphql +4 -0
  3. package/Api/OrderPlaced.gql.ts +4 -0
  4. package/Api/OrderPlaced.graphql +3 -0
  5. package/Api/PaymentMethod.ts +38 -0
  6. package/Api/PaymentMethodContext.gql.ts +4 -0
  7. package/Api/PaymentMethodContext.graphql +8 -0
  8. package/Api/PaymentMethodUpdated.gql.ts +4 -0
  9. package/Api/PaymentMethodUpdated.graphql +6 -0
  10. package/Api/SelectedPaymentMethod/SelectedPaymentMethod.gql.ts +4 -0
  11. package/Api/SelectedPaymentMethod/SelectedPaymentMethod.graphql +4 -0
  12. package/CHANGELOG.md +135 -0
  13. package/PaymentMethodButton/PaymentMethodButton.tsx +77 -0
  14. package/PaymentMethodContext/GetPaymentMethodContext.gql.ts +12 -0
  15. package/PaymentMethodContext/GetPaymentMethodContext.graphql +7 -0
  16. package/PaymentMethodContext/PaymentMethodContext.tsx +76 -0
  17. package/PaymentMethodOptions/PaymentMethodOptions.tsx +31 -0
  18. package/PaymentMethodOptionsNoop/PaymentMethodOptionsNoop.gql.ts +13 -0
  19. package/PaymentMethodOptionsNoop/PaymentMethodOptionsNoop.graphql +7 -0
  20. package/PaymentMethodOptionsNoop/PaymentMethodOptionsNoop.tsx +30 -0
  21. package/PaymentMethodPlaceOrder/PaymentMethodPlaceOrder.tsx +12 -0
  22. package/PaymentMethodPlaceOrderNoop/PaymentMethodPlaceOrderNoop.gql.ts +12 -0
  23. package/PaymentMethodPlaceOrderNoop/PaymentMethodPlaceOrderNoop.graphql +7 -0
  24. package/PaymentMethodPlaceOrderNoop/PaymentMethodPlaceOrderNoop.tsx +34 -0
  25. package/PaymentMethodToggle/PaymentMethodToggle.tsx +205 -0
  26. package/README.md +56 -0
  27. package/index.ts +18 -0
  28. package/package.json +43 -0
  29. package/tsconfig.json +5 -0
@@ -0,0 +1,4 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ export type AvailablePaymentMethodFragment = { code: string, title: string, mollie_available_issuers?: Types.Maybe<Array<Types.Maybe<{ code?: Types.Maybe<string>, image: string, name?: Types.Maybe<string>, svg: string }>>>, mollie_meta: { image?: Types.Maybe<string> } };
@@ -0,0 +1,4 @@
1
+ fragment AvailablePaymentMethod on AvailablePaymentMethod @injectable {
2
+ code
3
+ title
4
+ }
@@ -0,0 +1,4 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ export type OrderPlacedFragment = { order_number: string };
@@ -0,0 +1,3 @@
1
+ fragment OrderPlaced on Order @injectable {
2
+ order_number
3
+ }
@@ -0,0 +1,38 @@
1
+ import { AvailablePaymentMethod } from '@graphcommerce/graphql'
2
+ import { ButtonProps } from '@graphcommerce/next-ui/Button'
3
+ import { UseFormComposeOptions } from '@graphcommerce/react-hook-form'
4
+ import React from 'react'
5
+ import { AvailablePaymentMethodFragment } from './AvailablePaymentMethod/AvailablePaymentMethod.gql'
6
+ import { PaymentMethodContextFragment } from './PaymentMethodContext.gql'
7
+ import { SelectedPaymentMethodFragment } from './SelectedPaymentMethod/SelectedPaymentMethod.gql'
8
+
9
+ export type PaymentMethod = Partial<AvailablePaymentMethodFragment> &
10
+ Pick<AvailablePaymentMethod, 'code' | 'title'> & {
11
+ child: string
12
+ preferred?: boolean
13
+ selected?: SelectedPaymentMethodFragment
14
+ }
15
+
16
+ export type PaymentMethodOptionsProps = Pick<UseFormComposeOptions, 'step'> & {
17
+ Container: React.FC
18
+ }
19
+ export type PaymentButtonProps = PaymentMethod & { buttonProps: ButtonProps }
20
+ export type PaymentOptionsProps = PaymentMethod & PaymentMethodOptionsProps
21
+
22
+ export type PaymentToggleProps = PaymentMethod
23
+ export type ExpandPaymentMethods = (
24
+ available: AvailablePaymentMethodFragment,
25
+ context: PaymentMethodContextFragment,
26
+ ) => Promise<PaymentMethod[]> | PaymentMethod[]
27
+
28
+ export type PaymentPlaceOrderProps = PaymentMethod & Pick<UseFormComposeOptions, 'step'>
29
+
30
+ export interface PaymentModule {
31
+ PaymentOptions: React.VFC<PaymentOptionsProps>
32
+ PaymentPlaceOrder: React.VFC<PaymentPlaceOrderProps>
33
+ PaymentButton?: React.VFC<PaymentButtonProps>
34
+ PaymentToggle?: React.VFC<PaymentToggleProps>
35
+ expandMethods?: ExpandPaymentMethods
36
+ }
37
+
38
+ export type PaymentMethodModules = { [code: string]: PaymentModule }
@@ -0,0 +1,4 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ export type PaymentMethodContextFragment = { available_payment_methods?: Types.Maybe<Array<Types.Maybe<{ code: string, title: string, mollie_available_issuers?: Types.Maybe<Array<Types.Maybe<{ code?: Types.Maybe<string>, image: string, name?: Types.Maybe<string>, svg: string }>>>, mollie_meta: { image?: Types.Maybe<string> } }>>>, selected_payment_method?: Types.Maybe<{ code: string, title: string, purchase_order_number?: Types.Maybe<string>, mollie_meta: { image?: Types.Maybe<string> } }>, shipping_addresses: Array<Types.Maybe<{ country: { code: string } }>>, prices?: Types.Maybe<{ grand_total?: Types.Maybe<{ currency?: Types.Maybe<Types.CurrencyEnum>, value?: Types.Maybe<number> }> }> };
@@ -0,0 +1,8 @@
1
+ fragment PaymentMethodContext on Cart @injectable {
2
+ available_payment_methods {
3
+ ...AvailablePaymentMethod
4
+ }
5
+ selected_payment_method {
6
+ ...SelectedPaymentMethod
7
+ }
8
+ }
@@ -0,0 +1,4 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ export type PaymentMethodUpdatedFragment = { id: string, selected_payment_method?: Types.Maybe<{ code: string, title: string, purchase_order_number?: Types.Maybe<string>, mollie_meta: { image?: Types.Maybe<string> } }> };
@@ -0,0 +1,6 @@
1
+ fragment PaymentMethodUpdated on Cart @injectable {
2
+ id
3
+ selected_payment_method {
4
+ ...SelectedPaymentMethod
5
+ }
6
+ }
@@ -0,0 +1,4 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ export type SelectedPaymentMethodFragment = { code: string, title: string, purchase_order_number?: Types.Maybe<string>, mollie_meta: { image?: Types.Maybe<string> } };
@@ -0,0 +1,4 @@
1
+ fragment SelectedPaymentMethod on SelectedPaymentMethod @injectable {
2
+ code
3
+ title
4
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,135 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [2.105.1](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.105.0...@graphcommerce/magento-cart-payment-method@2.105.1) (2021-09-27)
7
+
8
+ **Note:** Version bump only for package @graphcommerce/magento-cart-payment-method
9
+
10
+
11
+
12
+
13
+
14
+ # 2.105.0 (2021-09-27)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **checkout:** purchaseorder and other build in methods wouldnt properly submit ([331cb8e](https://github.com/ho-nl/m2-pwa/commit/331cb8e2bed58c14cd41fceeab03e2cdfbe7e6a9))
20
+ * do not use ToggleButtonGroup, only use the ToggleButton ([5172f70](https://github.com/ho-nl/m2-pwa/commit/5172f709ee26122b0a8700afb4325f23cb9ba9b9))
21
+ * ignore md files from triggering version updates ([4f98392](https://github.com/ho-nl/m2-pwa/commit/4f9839250b3a32d3070da5290e5efcc5e2243fba))
22
+ * implement next-ui barrel imports ([75bea70](https://github.com/ho-nl/m2-pwa/commit/75bea703dba898f18a2a1dfa3243ebd0a4e6f0e1))
23
+ * paymentDone removed in favor of a more simple clearCart method ([5314f77](https://github.com/ho-nl/m2-pwa/commit/5314f7752c2f75a55dcd926bfc26607124561e5d))
24
+ * playwright can't find the place order button ([b1fda5b](https://github.com/ho-nl/m2-pwa/commit/b1fda5b3e403dad621aba8ed895427f2166bc985))
25
+ * **playwright:** checkout button was renamed ([09e5b79](https://github.com/ho-nl/m2-pwa/commit/09e5b79333708cfac04232d8071d1dad72968297))
26
+ * rename NextButton to Button, change imports ([976adb0](https://github.com/ho-nl/m2-pwa/commit/976adb0bf906310d1efce888dcc9be1e28ce0f1b))
27
+
28
+
29
+ ### Features
30
+
31
+ * **cart:** when a cart is not active anymore show a clear cart button ([5d04a14](https://github.com/ho-nl/m2-pwa/commit/5d04a14726c040b20b34c0b88f923aee1dff22e5))
32
+ * coupon form on payment page ([a163961](https://github.com/ho-nl/m2-pwa/commit/a1639617be756b357177fcce255cf662c5314499))
33
+ * **graphql:** introduced new graphql package that holds all generated files ([a3e7aa0](https://github.com/ho-nl/m2-pwa/commit/a3e7aa05540540533b5ced9a95f1f802ecbe499f))
34
+ * **image:** introduced completely rewritten Image component ([e3413b3](https://github.com/ho-nl/m2-pwa/commit/e3413b3a57392d6571ea64cb8d9c8dca05ea31df))
35
+ * implemented checkmo payment method ([18525b2](https://github.com/ho-nl/m2-pwa/commit/18525b2f4efe9bd0eea12a7a992d284f341e0c68))
36
+ * implemented purchase order ([3a40033](https://github.com/ho-nl/m2-pwa/commit/3a40033cd4d6712a17bb9c41a8841ebf7aa2f025))
37
+ * implemented the new mollie payment api ([a8b38a9](https://github.com/ho-nl/m2-pwa/commit/a8b38a9a45207e180f795e81bf5ac759f01a583d))
38
+ * **mollie:** first version of mollie payment methods ([e2f7d78](https://github.com/ho-nl/m2-pwa/commit/e2f7d78e50a9afe928f1d8c478f946e03c63b0f2))
39
+ * **mollie:** pay with credit card made working ([5cda84e](https://github.com/ho-nl/m2-pwa/commit/5cda84e0b9c54238ae6adaa34f9e2ad77a708508))
40
+ * next.js 11 ([7d61407](https://github.com/ho-nl/m2-pwa/commit/7d614075a778f488045034f74be4f75b93f63c43))
41
+ * only show free payment method when zero subtotal quote ([fd3ba86](https://github.com/ho-nl/m2-pwa/commit/fd3ba86d3060ebe7dc72ce27fca21464b46b4392))
42
+ * **payment-agreements-form:** checkout agreements checkboxes ([13c8164](https://github.com/ho-nl/m2-pwa/commit/13c816499d220a2ce940672a95beca508b78ddc9))
43
+ * **payments:** make PaymentMethodContext injectable ([68c664a](https://github.com/ho-nl/m2-pwa/commit/68c664adb7eb6eb86d7a819213deb87152392347))
44
+ * **playwright:** added new playwright package to enable browser testing ([6f49ec7](https://github.com/ho-nl/m2-pwa/commit/6f49ec7595563775b96ebf21c27e39da1282e8d9))
45
+ * **react-hook-form:** added buttonState to ComposedSubmit ([57e77c2](https://github.com/ho-nl/m2-pwa/commit/57e77c29f17720f7f3ee3b63be82779c0e5d8714))
46
+ * renamed all packages to use [@graphcommerce](https://github.com/graphcommerce) instead of [@reachdigital](https://github.com/reachdigital) ([491e4ce](https://github.com/ho-nl/m2-pwa/commit/491e4cec9a2686472dac36b79f999257c0811ffe))
47
+ * solve issue where the order couldn’t be submitted ([ec0d357](https://github.com/ho-nl/m2-pwa/commit/ec0d3579a1277976e2dc515f420996cf716f83a6))
48
+ * upgraded to nextjs 11 ([0053beb](https://github.com/ho-nl/m2-pwa/commit/0053beb7ef597c190add7264256a0eaec35868da))
49
+ * useFormMutationCart and simpler imports ([012f090](https://github.com/ho-nl/m2-pwa/commit/012f090e8f54d09f35d393c61ad1e2319f5a90ff))
50
+
51
+
52
+ ### Reverts
53
+
54
+ * Revert "chore: upgrade @apollo/client" ([55ff24e](https://github.com/ho-nl/m2-pwa/commit/55ff24ede0e56c85b8095edadadd1ec5e0b1b8d2))
55
+
56
+
57
+
58
+
59
+
60
+ # Change Log
61
+
62
+ All notable changes to this project will be documented in this file. See
63
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
64
+
65
+ # [2.104.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.103.18...@graphcommerce/magento-cart-payment-method@2.104.0) (2021-09-24)
66
+
67
+ ### Features
68
+
69
+ - **payment-agreements-form:** checkout agreements checkboxes
70
+ ([13c8164](https://github.com/ho-nl/m2-pwa/commit/13c816499d220a2ce940672a95beca508b78ddc9))
71
+
72
+ ## [2.103.15](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.103.14...@graphcommerce/magento-cart-payment-method@2.103.15) (2021-09-23)
73
+
74
+ ## [2.103.15](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.103.14...@graphcommerce/magento-cart-payment-method@2.103.15) (2021-09-23)
75
+
76
+ ### Bug Fixes
77
+
78
+ - do not use ToggleButtonGroup, only use the ToggleButton
79
+ ([5172f70](https://github.com/ho-nl/m2-pwa/commit/5172f709ee26122b0a8700afb4325f23cb9ba9b9))
80
+
81
+ ## [2.103.12](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.103.11...@graphcommerce/magento-cart-payment-method@2.103.12) (2021-09-01)
82
+
83
+ ### Bug Fixes
84
+
85
+ - playwright can't find the place order button
86
+ ([b1fda5b](https://github.com/ho-nl/m2-pwa/commit/b1fda5b3e403dad621aba8ed895427f2166bc985))
87
+
88
+ ## [2.103.4](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.103.3...@graphcommerce/magento-cart-payment-method@2.103.4) (2021-08-17)
89
+
90
+ ### Bug Fixes
91
+
92
+ - **playwright:** checkout button was renamed
93
+ ([09e5b79](https://github.com/ho-nl/m2-pwa/commit/09e5b79333708cfac04232d8071d1dad72968297))
94
+
95
+ # [2.103.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.102.2...@graphcommerce/magento-cart-payment-method@2.103.0) (2021-08-13)
96
+
97
+ ### Features
98
+
99
+ - coupon form on payment page
100
+ ([a163961](https://github.com/ho-nl/m2-pwa/commit/a1639617be756b357177fcce255cf662c5314499))
101
+
102
+ # [2.102.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.101.10...@graphcommerce/magento-cart-payment-method@2.102.0) (2021-08-12)
103
+
104
+ ### Features
105
+
106
+ - upgraded to nextjs 11
107
+ ([0053beb](https://github.com/ho-nl/m2-pwa/commit/0053beb7ef597c190add7264256a0eaec35868da))
108
+
109
+ ## [2.101.9](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.101.8...@graphcommerce/magento-cart-payment-method@2.101.9) (2021-08-09)
110
+
111
+ ### Reverts
112
+
113
+ - Revert "chore: upgrade @apollo/client"
114
+ ([55ff24e](https://github.com/ho-nl/m2-pwa/commit/55ff24ede0e56c85b8095edadadd1ec5e0b1b8d2))
115
+
116
+ ## [2.101.3](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.101.2...@graphcommerce/magento-cart-payment-method@2.101.3) (2021-07-29)
117
+
118
+ ### Bug Fixes
119
+
120
+ - paymentDone removed in favor of a more simple clearCart method
121
+ ([5314f77](https://github.com/ho-nl/m2-pwa/commit/5314f7752c2f75a55dcd926bfc26607124561e5d))
122
+
123
+ # [2.101.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.100.19...@graphcommerce/magento-cart-payment-method@2.101.0) (2021-07-26)
124
+
125
+ ### Features
126
+
127
+ - **playwright:** added new playwright package to enable browser testing
128
+ ([6f49ec7](https://github.com/ho-nl/m2-pwa/commit/6f49ec7595563775b96ebf21c27e39da1282e8d9))
129
+
130
+ ## [2.100.11](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/magento-cart-payment-method@2.100.10...@graphcommerce/magento-cart-payment-method@2.100.11) (2021-07-20)
131
+
132
+ ### Bug Fixes
133
+
134
+ - ignore md files from triggering version updates
135
+ ([4f98392](https://github.com/ho-nl/m2-pwa/commit/4f9839250b3a32d3070da5290e5efcc5e2243fba))
@@ -0,0 +1,77 @@
1
+ import { ApolloCartErrorAlert } from '@graphcommerce/magento-cart'
2
+ import { Button, ButtonProps, FormRow } from '@graphcommerce/next-ui'
3
+ import { ComposedSubmit, ComposedSubmitRenderComponentProps } from '@graphcommerce/react-hook-form'
4
+ import React from 'react'
5
+ import { usePaymentMethodContext } from '../PaymentMethodContext/PaymentMethodContext'
6
+
7
+ export type PaymentMethodButtonProps = ButtonProps & { display?: 'inline' | 'block' }
8
+
9
+ export function PaymentMethodButtonRenderer(
10
+ props: { buttonProps: ButtonProps } & ComposedSubmitRenderComponentProps,
11
+ ) {
12
+ const { buttonProps, error, buttonState, submit } = props
13
+ const { selectedMethod, selectedModule } = usePaymentMethodContext()
14
+
15
+ const btnProps = { ...buttonProps, name: 'placeOrder' }
16
+
17
+ const PaymentButton = selectedModule?.PaymentButton
18
+
19
+ return (
20
+ <>
21
+ {!PaymentButton || !selectedMethod?.code ? (
22
+ <Button
23
+ {...btnProps}
24
+ onClick={submit}
25
+ loading={buttonState.isSubmitting || (buttonState.isSubmitSuccessful && !error)}
26
+ >
27
+ {btnProps.children}
28
+ {selectedMethod?.title && (
29
+ <>
30
+ {' '}
31
+ (<em>{selectedMethod?.title}</em>)
32
+ </>
33
+ )}
34
+ </Button>
35
+ ) : (
36
+ <PaymentButton
37
+ {...selectedMethod}
38
+ buttonProps={{
39
+ ...btnProps,
40
+ onClick: submit,
41
+ loading: buttonState.isSubmitting || (buttonState.isSubmitSuccessful && !error),
42
+ }}
43
+ />
44
+ )}
45
+ </>
46
+ )
47
+ }
48
+
49
+ export default function PaymentMethodButton(props: PaymentMethodButtonProps) {
50
+ const { display, ...buttonProps } = props
51
+
52
+ return (
53
+ <ComposedSubmit
54
+ render={({ submit, buttonState, error }) => {
55
+ const button = (
56
+ <PaymentMethodButtonRenderer
57
+ buttonProps={buttonProps}
58
+ submit={submit}
59
+ buttonState={buttonState}
60
+ error={error}
61
+ />
62
+ )
63
+ return display === 'inline' ? (
64
+ button
65
+ ) : (
66
+ <>
67
+ <FormRow>{button}</FormRow>
68
+ <ApolloCartErrorAlert
69
+ key='error'
70
+ error={buttonState.isSubmitting ? undefined : error}
71
+ />
72
+ </>
73
+ )
74
+ }}
75
+ />
76
+ )
77
+ }
@@ -0,0 +1,12 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
5
+
6
+ export const GetPaymentMethodContextDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetPaymentMethodContext"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cartId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cart"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"cart_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cartId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"available_payment_methods"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"mollie_available_issuers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"svg"}}]}},{"kind":"Field","name":{"kind":"Name","value":"mollie_meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"image"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"selected_payment_method"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"purchase_order_number"}},{"kind":"Field","name":{"kind":"Name","value":"mollie_meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"image"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"shipping_addresses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"prices"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"grand_total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}}]}}]}}]}}]} as unknown as DocumentNode<GetPaymentMethodContextQuery, GetPaymentMethodContextQueryVariables>;
7
+ export type GetPaymentMethodContextQueryVariables = Types.Exact<{
8
+ cartId: Types.Scalars['String'];
9
+ }>;
10
+
11
+
12
+ export type GetPaymentMethodContextQuery = { cart?: Types.Maybe<{ __typename: 'Cart', id: string, available_payment_methods?: Types.Maybe<Array<Types.Maybe<{ code: string, title: string, mollie_available_issuers?: Types.Maybe<Array<Types.Maybe<{ code?: Types.Maybe<string>, image: string, name?: Types.Maybe<string>, svg: string }>>>, mollie_meta: { image?: Types.Maybe<string> } }>>>, selected_payment_method?: Types.Maybe<{ code: string, title: string, purchase_order_number?: Types.Maybe<string>, mollie_meta: { image?: Types.Maybe<string> } }>, shipping_addresses: Array<Types.Maybe<{ country: { code: string } }>>, prices?: Types.Maybe<{ grand_total?: Types.Maybe<{ currency?: Types.Maybe<Types.CurrencyEnum>, value?: Types.Maybe<number> }> }> }> };
@@ -0,0 +1,7 @@
1
+ query GetPaymentMethodContext($cartId: String!) {
2
+ cart(cart_id: $cartId) {
3
+ id
4
+ __typename
5
+ ...PaymentMethodContext
6
+ }
7
+ }
@@ -0,0 +1,76 @@
1
+ import { useCartQuery } from '@graphcommerce/magento-cart'
2
+ import React, { PropsWithChildren, useContext, useEffect, useState } from 'react'
3
+ import { PaymentMethod, PaymentMethodModules, PaymentModule } from '../Api/PaymentMethod'
4
+ import { GetPaymentMethodContextDocument } from './GetPaymentMethodContext.gql'
5
+
6
+ type PaymentMethodContextProps = {
7
+ methods: PaymentMethod[]
8
+ selectedMethod?: PaymentMethod
9
+ setSelectedMethod(method: PaymentMethod | undefined): void
10
+ modules: PaymentMethodModules
11
+ selectedModule?: PaymentModule
12
+ setSelectedModule(module: PaymentModule | undefined): void
13
+ }
14
+
15
+ const paymentMethodContext = React.createContext<PaymentMethodContextProps>({
16
+ methods: [],
17
+ setSelectedMethod: () => {},
18
+ modules: {},
19
+ setSelectedModule: () => {},
20
+ })
21
+ paymentMethodContext.displayName = 'PaymentMethodContext'
22
+
23
+ type PaymentMethodContextProviderProps = PropsWithChildren<{ modules: PaymentMethodModules }>
24
+
25
+ export default function PaymentMethodContextProvider(props: PaymentMethodContextProviderProps) {
26
+ const { modules, children } = props
27
+
28
+ const context = useCartQuery(GetPaymentMethodContextDocument)
29
+ const cartContext = context?.data?.cart
30
+ const [methods, setMethods] = useState<PaymentMethod[]>([])
31
+ const [selectedMethod, setSelectedMethod] = useState<PaymentMethod>()
32
+ const [selectedModule, setSelectedModule] = useState<PaymentModule>()
33
+
34
+ // Expand the payment methods
35
+ useEffect(() => {
36
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
37
+ ;(async () => {
38
+ if (!cartContext) return
39
+
40
+ const freeMethod = cartContext.available_payment_methods?.find(
41
+ (method) => method?.code === 'free',
42
+ )
43
+
44
+ const promises =
45
+ [...(freeMethod ? [freeMethod] : cartContext.available_payment_methods ?? [])].map(
46
+ async (method) =>
47
+ method
48
+ ? modules?.[method.code]?.expandMethods?.(method, cartContext) ?? [
49
+ { ...method, child: '' },
50
+ ]
51
+ : Promise.resolve([]),
52
+ ) ?? []
53
+
54
+ setMethods((await Promise.all(promises)).flat(1).sort((a) => (a.preferred ? 1 : 0)))
55
+ })()
56
+ }, [cartContext, modules])
57
+
58
+ return (
59
+ <paymentMethodContext.Provider
60
+ value={{
61
+ methods,
62
+ selectedMethod,
63
+ setSelectedMethod,
64
+ modules,
65
+ selectedModule,
66
+ setSelectedModule,
67
+ }}
68
+ >
69
+ {children}
70
+ </paymentMethodContext.Provider>
71
+ )
72
+ }
73
+
74
+ export function usePaymentMethodContext() {
75
+ return useContext(paymentMethodContext)
76
+ }
@@ -0,0 +1,31 @@
1
+ import { makeStyles, Theme } from '@material-ui/core'
2
+ import { AnimatedRow } from '@graphcommerce/next-ui'
3
+ import { AnimatePresence } from 'framer-motion'
4
+ import { PaymentMethodOptionsProps } from '../Api/PaymentMethod'
5
+ import { usePaymentMethodContext } from '../PaymentMethodContext/PaymentMethodContext'
6
+
7
+ const useStyles = makeStyles(
8
+ (theme: Theme) => ({
9
+ root: {
10
+ marginBottom: theme.spacings.sm,
11
+ },
12
+ }),
13
+ { name: 'PaymentMethodOptions' },
14
+ )
15
+
16
+ export default function PaymentMethodOptions(props: PaymentMethodOptionsProps) {
17
+ const { selectedMethod, selectedModule } = usePaymentMethodContext()
18
+ const classes = useStyles()
19
+
20
+ return (
21
+ <div className={classes.root}>
22
+ <AnimatePresence initial={false}>
23
+ {selectedModule && selectedMethod && (
24
+ <AnimatedRow key={selectedMethod.code}>
25
+ <selectedModule.PaymentOptions {...selectedMethod} {...props} />
26
+ </AnimatedRow>
27
+ )}
28
+ </AnimatePresence>
29
+ </div>
30
+ )
31
+ }
@@ -0,0 +1,13 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
5
+
6
+ export const PaymentMethodOptionsNoopDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"PaymentMethodOptionsNoop"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cartId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"code"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setPaymentMethodOnCart"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"cart_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cartId"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"payment_method"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"code"},"value":{"kind":"Variable","name":{"kind":"Name","value":"code"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cart"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"selected_payment_method"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"purchase_order_number"}},{"kind":"Field","name":{"kind":"Name","value":"mollie_meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"image"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<PaymentMethodOptionsNoopMutation, PaymentMethodOptionsNoopMutationVariables>;
7
+ export type PaymentMethodOptionsNoopMutationVariables = Types.Exact<{
8
+ cartId: Types.Scalars['String'];
9
+ code: Types.Scalars['String'];
10
+ }>;
11
+
12
+
13
+ export type PaymentMethodOptionsNoopMutation = { setPaymentMethodOnCart?: Types.Maybe<{ cart: { id: string, selected_payment_method?: Types.Maybe<{ code: string, title: string, purchase_order_number?: Types.Maybe<string>, mollie_meta: { image?: Types.Maybe<string> } }> } }> };
@@ -0,0 +1,7 @@
1
+ mutation PaymentMethodOptionsNoop($cartId: String!, $code: String!) {
2
+ setPaymentMethodOnCart(input: { cart_id: $cartId, payment_method: { code: $code } }) {
3
+ cart {
4
+ ...PaymentMethodUpdated
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,30 @@
1
+ import { useFormGqlMutationCart } from '@graphcommerce/magento-cart'
2
+ import { useFormCompose } from '@graphcommerce/react-hook-form'
3
+ import { PaymentOptionsProps } from '../Api/PaymentMethod'
4
+ import { PaymentMethodOptionsNoopDocument } from './PaymentMethodOptionsNoop.gql'
5
+
6
+ /** It sets the selected payment method on the cart. */
7
+ function PaymentMethodOptionsNoop(props: PaymentOptionsProps) {
8
+ const { code, step } = props
9
+
10
+ /**
11
+ * In the this folder you'll also find a PaymentMethodOptionsNoop.graphql document that is
12
+ * imported here and used as the basis for the form below.
13
+ */
14
+ const form = useFormGqlMutationCart(PaymentMethodOptionsNoopDocument, { defaultValues: { code } })
15
+
16
+ const { handleSubmit, register } = form
17
+ const submit = handleSubmit(() => {})
18
+
19
+ /** To use an external Pay button we register the current form to be handled there as well. */
20
+ useFormCompose({ form, step, submit, key: `PaymentMethodOptions_${code}` })
21
+
22
+ /** This is the form that the user can fill in. In this case we don't wat the user to fill in anything. */
23
+ return (
24
+ <form onSubmit={submit} style={{ visibility: 'hidden' }}>
25
+ <input type='hidden' {...register('code')} />
26
+ </form>
27
+ )
28
+ }
29
+
30
+ export default PaymentMethodOptionsNoop
@@ -0,0 +1,12 @@
1
+ import { UseFormComposeOptions } from '@graphcommerce/react-hook-form'
2
+ import { usePaymentMethodContext } from '../PaymentMethodContext/PaymentMethodContext'
3
+
4
+ export type PaymentMethodPlaceOrderProps = Pick<UseFormComposeOptions, 'step'>
5
+
6
+ export default function PaymentMethodPlaceOrder(props: PaymentMethodPlaceOrderProps) {
7
+ const { step } = props
8
+ const { selectedMethod, selectedModule } = usePaymentMethodContext()
9
+
10
+ if (!selectedModule || !selectedMethod?.code) return null
11
+ return <selectedModule.PaymentPlaceOrder {...selectedMethod} step={step} />
12
+ }
@@ -0,0 +1,12 @@
1
+ /* eslint-disable */
2
+ import * as Types from '@graphcommerce/graphql';
3
+
4
+ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
5
+
6
+ export const PaymentMethodPlaceOrderNoopDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"PaymentMethodPlaceOrderNoop"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cartId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"placeOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"cart_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cartId"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order_number"}}]}}]}}]}}]} as unknown as DocumentNode<PaymentMethodPlaceOrderNoopMutation, PaymentMethodPlaceOrderNoopMutationVariables>;
7
+ export type PaymentMethodPlaceOrderNoopMutationVariables = Types.Exact<{
8
+ cartId: Types.Scalars['String'];
9
+ }>;
10
+
11
+
12
+ export type PaymentMethodPlaceOrderNoopMutation = { placeOrder?: Types.Maybe<{ order: { order_number: string } }> };
@@ -0,0 +1,7 @@
1
+ mutation PaymentMethodPlaceOrderNoop($cartId: String!) {
2
+ placeOrder(input: { cart_id: $cartId }) {
3
+ order {
4
+ order_number
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,34 @@
1
+ import {
2
+ useFormGqlMutationCart,
3
+ useCurrentCartId,
4
+ useClearCurrentCartId,
5
+ } from '@graphcommerce/magento-cart'
6
+ import { useFormCompose } from '@graphcommerce/react-hook-form'
7
+ import { useRouter } from 'next/router'
8
+ import { useEffect } from 'react'
9
+ import { PaymentPlaceOrderProps } from '../Api/PaymentMethod'
10
+ import { PaymentMethodPlaceOrderNoopDocument } from './PaymentMethodPlaceOrderNoop.gql'
11
+
12
+ export default function PaymentMethodPlaceOrderNoop(props: PaymentPlaceOrderProps) {
13
+ const { step, code } = props
14
+ const clearCurrentCartId = useClearCurrentCartId()
15
+
16
+ const cartId = useCurrentCartId()
17
+ const form = useFormGqlMutationCart(PaymentMethodPlaceOrderNoopDocument, { mode: 'onChange' })
18
+
19
+ const { handleSubmit, data, error } = form
20
+ const router = useRouter()
21
+
22
+ useEffect(() => {
23
+ if (!data?.placeOrder?.order || error || !cartId) return
24
+ clearCurrentCartId?.()
25
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
26
+ router.push({ pathname: '/checkout/success', query: { cartId } })
27
+ }, [cartId, clearCurrentCartId, data?.placeOrder?.order, error, router])
28
+
29
+ const submit = handleSubmit(() => {})
30
+
31
+ useFormCompose({ form, step, submit, key: `PaymentMethodPlaceOrder_${code}` })
32
+
33
+ return <form onSubmit={submit} />
34
+ }
@@ -0,0 +1,205 @@
1
+ import { FormControl, makeStyles, Theme } from '@material-ui/core'
2
+ import { Scroller, ScrollerButton, ScrollerProvider } from '@graphcommerce/framer-scroller'
3
+ import {
4
+ Form,
5
+ FormRow,
6
+ iconChevronLeft,
7
+ iconChevronRight,
8
+ responsiveVal,
9
+ SvgImage,
10
+ ToggleButton,
11
+ } from '@graphcommerce/next-ui'
12
+ import { Controller, useForm, useFormPersist } from '@graphcommerce/react-hook-form'
13
+ import clsx from 'clsx'
14
+ import { m } from 'framer-motion'
15
+ import React, { useEffect } from 'react'
16
+ import { PaymentMethod, PaymentToggleProps } from '../Api/PaymentMethod'
17
+ import { usePaymentMethodContext } from '../PaymentMethodContext/PaymentMethodContext'
18
+
19
+ export type PaymentMethodToggleProps = Record<string, unknown>
20
+
21
+ function Content(props: PaymentMethod) {
22
+ const { code } = props
23
+ const { modules } = usePaymentMethodContext()
24
+ const Component = modules[code]?.PaymentToggle ?? ((p: PaymentToggleProps) => <>{p.title}</>)
25
+ return <Component {...props} />
26
+ }
27
+
28
+ const useStyles = makeStyles(
29
+ (theme: Theme) => ({
30
+ formRoot: {
31
+ padding: '5px 0',
32
+ },
33
+ root: {
34
+ position: 'relative',
35
+ padding: 0,
36
+ },
37
+ toggleGroup: {
38
+ display: 'inline-flex',
39
+ gap: 10,
40
+ },
41
+ buttonRoot: {
42
+ background: theme.palette.background.default,
43
+ borderRadius: 0,
44
+ width: 30,
45
+ height: responsiveVal(60, 85),
46
+ boxShadow: 'none',
47
+ border: '1px solid #eee',
48
+ '&:focus': {
49
+ boxShadow: 'none',
50
+ },
51
+ },
52
+ leftButtonRoot: {
53
+ borderTopLeftRadius: 4,
54
+ borderBottomLeftRadius: 4,
55
+ },
56
+ rightButtonRoot: {
57
+ borderTopRightRadius: 4,
58
+ borderBottomRightRadius: 4,
59
+ },
60
+ scrollerRoot: {
61
+ display: `grid`,
62
+ gridAutoFlow: `column`,
63
+ gridTemplateColumns: `repeat(30, max-content)`,
64
+ gridTemplateRows: `100%`,
65
+ gap: responsiveVal(4, 8),
66
+ height: responsiveVal(60, 85),
67
+ borderRadius: 5,
68
+ },
69
+ toggleButton: {
70
+ ...theme.typography.h5,
71
+ border: '1px solid #eee',
72
+ borderRadius: 4,
73
+ boxShadow: 'none',
74
+ transition: 'color .15s ease',
75
+ whiteSpace: 'nowrap',
76
+ fontSize: responsiveVal(14, 20),
77
+ [theme.breakpoints.up('sm')]: {
78
+ fontSize: responsiveVal(17, 20),
79
+ },
80
+ },
81
+ toggleButtonSelected: {
82
+ border: `1px solid ${theme.palette.secondary.main}`,
83
+ background: `${theme.palette.secondary.main}`,
84
+ color: `${theme.palette.secondary.contrastText}`,
85
+ '&:hover': {
86
+ background: `${theme.palette.secondary.main}`,
87
+ },
88
+ },
89
+ buttonContainer: {
90
+ position: 'absolute',
91
+ left: 0,
92
+ top: 0,
93
+ zIndex: 2,
94
+ height: '100%',
95
+ },
96
+ buttonContainerRight: {
97
+ left: 'unset',
98
+ right: 0,
99
+ },
100
+ }),
101
+ { name: 'PaymentMethodToggle' },
102
+ )
103
+
104
+ export default function PaymentMethodToggle(props: PaymentMethodToggleProps) {
105
+ const { methods, selectedMethod, setSelectedMethod, setSelectedModule, modules } =
106
+ usePaymentMethodContext()
107
+
108
+ const classes = useStyles()
109
+
110
+ const form = useForm<{ code: string; paymentMethod?: string }>({
111
+ mode: 'onChange',
112
+ defaultValues: { code: selectedMethod?.code },
113
+ })
114
+ useFormPersist({ form, name: 'PaymentMethodToggle' })
115
+
116
+ const { control, handleSubmit, watch, register, setValue } = form
117
+ const submitHandler = handleSubmit(() => {})
118
+
119
+ const paymentMethod = watch('paymentMethod')
120
+ useEffect(() => {
121
+ const [code, child] = paymentMethod?.split('___') ?? ['']
122
+ if (code === selectedMethod?.code) return
123
+
124
+ const foundMethod = methods.find(
125
+ (method) => method.code === code && (!child || method.child === child),
126
+ )
127
+ if (foundMethod && !modules?.[foundMethod?.code ?? '']) {
128
+ console.error(`No PaymentModule found for method ${foundMethod.code}`)
129
+ }
130
+ setSelectedMethod(foundMethod)
131
+ setSelectedModule(modules?.[foundMethod?.code ?? ''])
132
+ }, [methods, modules, paymentMethod, selectedMethod?.code, setSelectedMethod, setSelectedModule])
133
+
134
+ if (!methods || methods.length < 1) return <></>
135
+
136
+ return (
137
+ <Form onSubmit={submitHandler} noValidate classes={{ root: classes.formRoot }}>
138
+ <input type='hidden' {...register('code', { required: true })} required />
139
+ <FormRow className={classes.root}>
140
+ <ScrollerProvider scrollSnapType='none'>
141
+ <m.div className={classes.buttonContainer}>
142
+ <ScrollerButton
143
+ direction='left'
144
+ classes={{
145
+ root: clsx(classes.buttonRoot, classes.leftButtonRoot),
146
+ }}
147
+ >
148
+ <SvgImage src={iconChevronLeft} alt='chevron left' size='small' loading='eager' />
149
+ </ScrollerButton>
150
+ </m.div>
151
+
152
+ <FormControl>
153
+ <Controller
154
+ defaultValue=''
155
+ control={control}
156
+ name='paymentMethod'
157
+ rules={{ required: 'Please select a payment method' }}
158
+ render={({ field: { onChange, value, name, ref, onBlur } }) => (
159
+ <Scroller className={classes.scrollerRoot} hideScrollbar>
160
+ {methods?.map((pm) => {
161
+ const buttonValue = `${pm.code}___${pm.child}`
162
+
163
+ return (
164
+ <ToggleButton
165
+ name={name}
166
+ aria-label={`payment_method_${pm.code}___${pm.child}`}
167
+ key={buttonValue}
168
+ value={buttonValue}
169
+ color='secondary'
170
+ disabled={!modules?.[pm.code]}
171
+ classes={{
172
+ root: classes.toggleButton,
173
+ selected: classes.toggleButtonSelected,
174
+ }}
175
+ onChange={(_, v: string) => {
176
+ onChange(v)
177
+ setValue('code', v)
178
+ }}
179
+ onBlur={onBlur}
180
+ selected={value === buttonValue}
181
+ >
182
+ {!modules?.[pm.code] ? <>{pm.code}</> : <>{pm.title}</>}
183
+ </ToggleButton>
184
+ )
185
+ })}
186
+ </Scroller>
187
+ )}
188
+ />
189
+ </FormControl>
190
+
191
+ <m.div className={clsx(classes.buttonContainer, classes.buttonContainerRight)}>
192
+ <ScrollerButton
193
+ direction='right'
194
+ classes={{
195
+ root: clsx(classes.buttonRoot, classes.rightButtonRoot),
196
+ }}
197
+ >
198
+ <SvgImage src={iconChevronRight} alt='chevron right' size='small' loading='eager' />
199
+ </ScrollerButton>
200
+ </m.div>
201
+ </ScrollerProvider>
202
+ </FormRow>
203
+ </Form>
204
+ )
205
+ }
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # Magento Payment
2
+
3
+ Defines the API's and building blocks to create payment methods in the checkout.
4
+
5
+ ## Flow
6
+
7
+ ## Payment Method module
8
+
9
+ A Magento Payment Method module must implement
10
+ [`PaymentModule`]('./PaymentMethods')
11
+
12
+ ```tsx
13
+ export interface PaymentModule {
14
+ PaymentOptions: React.VFC<PaymentOptionsProps>
15
+ PaymentButton?: React.VFC<PaymentButtonProps>
16
+ PaymentToggle?: React.VFC<PaymentToggleProps>
17
+ expandMethods?: ExpandPaymentMethods
18
+ }
19
+ ```
20
+
21
+ ## Creating a payment method
22
+
23
+ If a payment method is not implemented it will show a console error
24
+ `No PaymentModule found for method ${code}`
25
+
26
+ ### 1. Create the module
27
+
28
+ ```tsx
29
+ import {
30
+ PaymentMethodOptionsNoop,
31
+ PaymentMethodPlaceOrderNoop,
32
+ PaymentModule,
33
+ } from '@graphcommerce/magento-cart-payment-method'
34
+
35
+ // This is the internal code of the payment method provided by Magento
36
+ export const braintree_local_payment = {
37
+ PaymentOptions: PaymentMethodOptionsNoop,
38
+ PaymentPlaceOrder: PaymentMethodPlaceOrderNoop,
39
+ } as PaymentModule
40
+ ```
41
+
42
+ ### 2. Register the module
43
+
44
+ On your payment page (`pages/checkout/payment.tsx` by default) pass in the
45
+ payment method into the PaymentMethodContextProvider:
46
+
47
+ ```tsx
48
+ <PaymentMethodContextProvider
49
+ modules={{ ...included_methods, braintree_local_payment }}
50
+ >
51
+ ```
52
+
53
+ ### 3. Customize setPaymentMethodOnCart
54
+
55
+ Open `PaymentMethodOptionsNoop` and `PaymentMethodPlaceOrderNoop` for details
56
+ how it is used.
package/index.ts ADDED
@@ -0,0 +1,18 @@
1
+ export * from './Api/PaymentMethod'
2
+
3
+ export * from './PaymentMethodContext/PaymentMethodContext'
4
+ export { default as PaymentMethodContextProvider } from './PaymentMethodContext/PaymentMethodContext'
5
+
6
+ export * from './PaymentMethodButton/PaymentMethodButton'
7
+ export { default as PaymentMethodButton } from './PaymentMethodButton/PaymentMethodButton'
8
+
9
+ export { default as PaymentMethodOptions } from './PaymentMethodOptions/PaymentMethodOptions'
10
+
11
+ export * from './PaymentMethodOptionsNoop/PaymentMethodOptionsNoop.gql'
12
+ export { default as PaymentMethodOptionsNoop } from './PaymentMethodOptionsNoop/PaymentMethodOptionsNoop'
13
+
14
+ export { default as PaymentMethodPlaceOrder } from './PaymentMethodPlaceOrder/PaymentMethodPlaceOrder'
15
+ export { default as PaymentMethodPlaceOrderNoop } from './PaymentMethodPlaceOrderNoop/PaymentMethodPlaceOrderNoop'
16
+
17
+ export * from './PaymentMethodToggle/PaymentMethodToggle'
18
+ export { default as PaymentMethodToggle } from './PaymentMethodToggle/PaymentMethodToggle'
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@graphcommerce/magento-cart-payment-method",
3
+ "version": "2.105.1",
4
+ "sideEffects": false,
5
+ "engines": {
6
+ "node": "14.x"
7
+ },
8
+ "prettier": "@graphcommerce/prettier-config-pwa",
9
+ "browserslist": [
10
+ "extends @graphcommerce/browserslist-config-pwa"
11
+ ],
12
+ "eslintConfig": {
13
+ "extends": "@graphcommerce/eslint-config-pwa",
14
+ "parserOptions": {
15
+ "project": "./tsconfig.json"
16
+ }
17
+ },
18
+ "devDependencies": {
19
+ "@graphcommerce/browserslist-config-pwa": "^3.0.1",
20
+ "@graphcommerce/eslint-config-pwa": "^3.0.1",
21
+ "@graphcommerce/prettier-config-pwa": "^3.0.1",
22
+ "@graphcommerce/typescript-config-pwa": "^3.0.1",
23
+ "@playwright/test": "^1.14.1"
24
+ },
25
+ "dependencies": {
26
+ "@apollo/client": "^3.3.21",
27
+ "@graphcommerce/graphql": "^2.103.1",
28
+ "@graphcommerce/image": "^2.104.1",
29
+ "@graphcommerce/magento-cart": "^3.0.1",
30
+ "@graphcommerce/magento-store": "^3.0.1",
31
+ "@graphcommerce/next-ui": "^3.0.1",
32
+ "@graphcommerce/react-hook-form": "^2.102.1",
33
+ "@graphql-typed-document-node/core": "^3.1.0",
34
+ "@material-ui/core": "^4.12.3",
35
+ "@material-ui/lab": "^4.0.0-alpha.60",
36
+ "clsx": "^1.1.1",
37
+ "framer-motion": "^4.1.17",
38
+ "next": "^11.1.2",
39
+ "react": "^17.0.1",
40
+ "react-dom": "^17.0.1",
41
+ "type-fest": "^2.1.0"
42
+ }
43
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "exclude": ["node_modules"],
3
+ "include": ["**/*.ts", "**/*.tsx", "../magento-payment-included/Checkmo.tsx"],
4
+ "extends": "@graphcommerce/typescript-config-pwa/nextjs.json"
5
+ }