diff --git a/src/Apps/Invoice/Components/AddressForm.tsx b/src/Apps/Invoice/Components/AddressForm.tsx
new file mode 100644
index 00000000000..4601313868a
--- /dev/null
+++ b/src/Apps/Invoice/Components/AddressForm.tsx
@@ -0,0 +1,118 @@
+import { Column, GridColumns, Input } from "@artsy/palette"
+import { CountrySelect } from "Components/CountrySelect"
+import { Address } from "Components/Address/AddressForm"
+import { useFormContext } from "Apps/Invoice/Hooks/useFormContext"
+
+export interface AddressFormValues {
+ address: Address
+ creditCard?: boolean
+}
+
+export const AddressForm = () => {
+ const { handleChange, handleBlur, errors, values, touched } = useFormContext()
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/Apps/Invoice/Components/AddressFormWithCreditCard.tsx b/src/Apps/Invoice/Components/AddressFormWithCreditCard.tsx
new file mode 100644
index 00000000000..7a407fc74ed
--- /dev/null
+++ b/src/Apps/Invoice/Components/AddressFormWithCreditCard.tsx
@@ -0,0 +1,42 @@
+import { Join, Spacer } from "@artsy/palette"
+import { CreditCardInput } from "Components/CreditCardInput"
+import { AddressForm } from "./AddressForm"
+import { useFormContext } from "Apps/Invoice/Hooks/useFormContext"
+
+export const AddressFormWithCreditCard: React.FC = () => {
+ const {
+ setFieldValue,
+ setFieldTouched,
+ setFieldError,
+ errors,
+ touched,
+ } = useFormContext()
+
+ return (
+ }>
+ {
+ setFieldTouched("creditCard", true)
+
+ if (event.error?.message) {
+ setFieldValue("creditCard", false)
+ setFieldError("creditCard", event.error?.message)
+ return
+ }
+ if (!event.complete) {
+ setFieldValue("creditCard", false)
+ return
+ }
+ if (event.complete) {
+ setFieldValue("creditCard", true)
+ return
+ }
+ }}
+ required
+ />
+
+
+
+ )
+}
diff --git a/src/Apps/Invoice/Components/InvoiceLineItems.tsx b/src/Apps/Invoice/Components/InvoiceLineItems.tsx
new file mode 100644
index 00000000000..ece44845ded
--- /dev/null
+++ b/src/Apps/Invoice/Components/InvoiceLineItems.tsx
@@ -0,0 +1,45 @@
+import { Box, Join, Separator, Text } from "@artsy/palette"
+import { graphql, useFragment } from "react-relay"
+import { InvoiceLineItems_invoice$key } from "__generated__/InvoiceLineItems_invoice.graphql"
+
+interface InvoiceLineItemsProps {
+ invoice: InvoiceLineItems_invoice$key
+}
+
+export const InvoiceLineItems: React.FC = ({
+ invoice,
+}) => {
+ const data = useFragment(InvoiceLineItemsFragment, invoice)
+
+ return (
+
+
+ Items
+
+
+ }>
+ {data.lineItems.map(({ description, amount }, index) => (
+ <>
+
+ {description}
+ {amount}
+
+ >
+ ))}
+
+
+ )
+}
+
+const InvoiceLineItemsFragment = graphql`
+ fragment InvoiceLineItems_invoice on Invoice {
+ lineItems {
+ description
+ amount(precision: 2)
+ }
+ }
+`
diff --git a/src/Apps/Invoice/Components/InvoicePaymentForm.tsx b/src/Apps/Invoice/Components/InvoicePaymentForm.tsx
new file mode 100644
index 00000000000..f0eef8e1a0d
--- /dev/null
+++ b/src/Apps/Invoice/Components/InvoicePaymentForm.tsx
@@ -0,0 +1,52 @@
+import { Button } from "@artsy/palette"
+import { AddressFormValues } from "Apps/Invoice/Components/AddressForm"
+import { AddressFormWithCreditCard } from "Apps/Invoice/Components/AddressFormWithCreditCard"
+import { useCreateTokenAndSubmit } from "Apps/Invoice/Hooks/useCreateTokenAndSubmit"
+import { emptyAddress } from "Components/Address/AddressForm"
+import { Formik, Form } from "formik"
+import { useRouter } from "System/Hooks/useRouter"
+
+export interface InvoicePaymentFormProps {
+ invoiceID: string
+ invoiceToken: string
+ amountMinor: number
+}
+
+export const InvoicePaymentForm: React.FC = props => {
+ const { match, router } = useRouter()
+ const token = match.params.token
+ const invoiceRoute = `/invoice/${token}`
+ const onSuccess = () => {
+ router.push(invoiceRoute)
+ }
+ const { createToken: handleSubmit } = useCreateTokenAndSubmit({
+ onSuccess,
+ ...props,
+ })
+
+ return (
+
+ onSubmit={handleSubmit}
+ initialValues={{ address: emptyAddress, creditCard: false }}
+ >
+ {({ isSubmitting, isValid }) => {
+ return (
+
+ )
+ }}
+
+ )
+}
diff --git a/src/Apps/Invoice/Components/InvoicePayments.tsx b/src/Apps/Invoice/Components/InvoicePayments.tsx
new file mode 100644
index 00000000000..abd2b65832f
--- /dev/null
+++ b/src/Apps/Invoice/Components/InvoicePayments.tsx
@@ -0,0 +1,67 @@
+import { Box, Column, GridColumns, Join, Separator, Text } from "@artsy/palette"
+import { graphql, useFragment } from "react-relay"
+import { InvoicePayments_invoice$key } from "__generated__/InvoicePayments_invoice.graphql"
+
+interface InvoiceLineItemsProps {
+ invoice: InvoicePayments_invoice$key
+}
+
+export const InvoicePayments: React.FC = ({
+ invoice,
+}) => {
+ const data = useFragment(InvoicePaymentsFragment, invoice)
+
+ return (
+
+
+ Payments
+
+
+ }>
+ {data.payments
+ .filter(({ successful }) => successful)
+ .map(({ id, createdAt, amount, creditCard }, index) => {
+ const creditCardInfo = creditCard
+ ? `${creditCard.brand} ending in ${creditCard.lastDigits}`
+ : null
+ return (
+ <>
+
+
+ {createdAt}
+
+
+ {creditCardInfo && (
+
+ {creditCardInfo}
+
+ )}
+
+
+
+ {amount}
+
+
+
+ >
+ )
+ })}
+
+
+ )
+}
+
+const InvoicePaymentsFragment = graphql`
+ fragment InvoicePayments_invoice on Invoice {
+ payments {
+ id
+ successful
+ createdAt(format: "MMM D, YYYY")
+ amount(precision: 2)
+ creditCard {
+ brand
+ lastDigits
+ }
+ }
+ }
+`
diff --git a/src/Apps/Invoice/Hooks/useCreateTokenAndSubmit.ts b/src/Apps/Invoice/Hooks/useCreateTokenAndSubmit.ts
new file mode 100644
index 00000000000..87e892f50be
--- /dev/null
+++ b/src/Apps/Invoice/Hooks/useCreateTokenAndSubmit.ts
@@ -0,0 +1,105 @@
+import {
+ CardCvcElement,
+ CardExpiryElement,
+ CardNumberElement,
+ useElements,
+ useStripe,
+} from "@stripe/react-stripe-js"
+import createLogger from "Utils/logger"
+import { toStripeAddress } from "Components/Address/AddressForm"
+import {
+ stripeCardElementNotFound,
+ stripeNotLoadedErrorMessage,
+} from "Apps/Auction/Components/Form/Utils/errorMessages"
+import { FormikHelpers } from "formik"
+import { AddressFormValues } from "Apps/Invoice/Components/AddressForm"
+import { useMakeInvoicePayment } from "Apps/Invoice/Hooks/useMakeInvoicePayment"
+import { InvoicePaymentFormProps } from "Apps/Invoice/Components/InvoicePaymentForm"
+import { useToasts } from "@artsy/palette"
+
+const logger = createLogger("useCreateTokenAndSubmit")
+
+export interface UseCreateTokenAndSubmitProps extends InvoicePaymentFormProps {
+ onSuccess: () => void
+}
+
+export const useCreateTokenAndSubmit = ({
+ onSuccess,
+ ...rest
+}: UseCreateTokenAndSubmitProps) => {
+ const stripe = useStripe()
+ const elements = useElements()
+ const { sendToast } = useToasts()
+
+ const { submitMutation: makeInvoicePaymentMutation } = useMakeInvoicePayment()
+
+ const createToken = async (
+ values: AddressFormValues,
+ helpers: FormikHelpers
+ ) => {
+ if (!stripe || !elements) {
+ logger.error(stripeNotLoadedErrorMessage)
+ helpers.setStatus("SUBMISSION_FAILED")
+ return
+ }
+
+ const cardNumberElement = elements.getElement(CardNumberElement)
+ const cardExpiryElement = elements.getElement(CardExpiryElement)
+ const cardCvcElement = elements.getElement(CardCvcElement)
+
+ if (!cardNumberElement || !cardExpiryElement || !cardCvcElement) {
+ logger.error(stripeCardElementNotFound)
+ helpers.setStatus("SUBMISSION_FAILED")
+ return
+ }
+
+ helpers.setSubmitting(true)
+
+ try {
+ const { error, token } = await stripe.createToken(
+ cardNumberElement,
+ toStripeAddress(values.address)
+ )
+
+ if (error) {
+ helpers.setFieldError("creditCard", error.message)
+ return
+ }
+
+ await makeInvoicePaymentMutation({
+ variables: {
+ input: {
+ creditCardToken: token.id,
+ provider: "stripe",
+ ...rest,
+ },
+ },
+ rejectIf: res => {
+ if (res.createInvoicePayment?.responseOrError?.mutationError) {
+ const errorMessage =
+ res.createInvoicePayment.responseOrError.mutationError.message
+
+ helpers.setFieldError("creditCard", errorMessage)
+
+ return errorMessage
+ }
+ },
+ })
+
+ sendToast({
+ variant: "success",
+ message: "Payment successful",
+ })
+
+ onSuccess()
+ } catch (error) {
+ helpers.setStatus("SUBMISSION_FAILED")
+ } finally {
+ helpers.setSubmitting(false)
+ }
+ }
+
+ return {
+ createToken,
+ }
+}
diff --git a/src/Apps/Invoice/Hooks/useFormContext.ts b/src/Apps/Invoice/Hooks/useFormContext.ts
new file mode 100644
index 00000000000..a38a23d8422
--- /dev/null
+++ b/src/Apps/Invoice/Hooks/useFormContext.ts
@@ -0,0 +1,7 @@
+import { AddressFormValues } from "Apps/Invoice/Components/AddressForm"
+import { useFormikContext } from "formik"
+
+export const useFormContext = () => {
+ const context = useFormikContext()
+ return context
+}
diff --git a/src/Apps/Invoice/Hooks/useMakeInvoicePayment.ts b/src/Apps/Invoice/Hooks/useMakeInvoicePayment.ts
new file mode 100644
index 00000000000..f1474a5f803
--- /dev/null
+++ b/src/Apps/Invoice/Hooks/useMakeInvoicePayment.ts
@@ -0,0 +1,25 @@
+import { useMutation } from "Utils/Hooks/useMutation"
+import { graphql } from "react-relay"
+import { useMakeInvoicePaymentMutation } from "__generated__/useMakeInvoicePaymentMutation.graphql"
+
+export const useMakeInvoicePayment = () => {
+ return useMutation({
+ mutation: graphql`
+ mutation useMakeInvoicePaymentMutation(
+ $input: CreateInvoicePaymentInput!
+ ) {
+ createInvoicePayment(input: $input) {
+ __typename
+
+ responseOrError {
+ ... on CreateInvoicePaymentFailure {
+ mutationError {
+ message
+ }
+ }
+ }
+ }
+ }
+ `,
+ })
+}
diff --git a/src/Apps/Invoice/InvoiceApp.tsx b/src/Apps/Invoice/InvoiceApp.tsx
new file mode 100644
index 00000000000..ba5066d814f
--- /dev/null
+++ b/src/Apps/Invoice/InvoiceApp.tsx
@@ -0,0 +1,51 @@
+import { Box, Separator, Spacer, Text } from "@artsy/palette"
+import { InvoiceApp_invoice$key } from "__generated__/InvoiceApp_invoice.graphql"
+import { HttpError } from "found"
+import { graphql, useFragment } from "react-relay"
+
+interface InvoiceAppProps {
+ invoice: InvoiceApp_invoice$key
+}
+
+export const InvoiceApp: React.FC = ({
+ invoice,
+ children,
+}) => {
+ const data = useFragment(InvoiceAppFragment, invoice)
+
+ if (!data) {
+ throw new HttpError(404)
+ }
+
+ const { number, readyAt } = data
+
+ return (
+
+
+
+
+
+ Invoice
+
+
+ Invoice #{number}
+
+ Date: {readyAt}
+
+
+
+
+
+
+
+ {children}
+
+ )
+}
+
+const InvoiceAppFragment = graphql`
+ fragment InvoiceApp_invoice on Invoice {
+ number
+ readyAt(format: "MMM D, YYYY")
+ }
+`
diff --git a/src/Apps/Invoice/Routes/InvoiceDetailRoute.tsx b/src/Apps/Invoice/Routes/InvoiceDetailRoute.tsx
new file mode 100644
index 00000000000..2933896513a
--- /dev/null
+++ b/src/Apps/Invoice/Routes/InvoiceDetailRoute.tsx
@@ -0,0 +1,99 @@
+import { Box, Button, Join, Separator, Text } from "@artsy/palette"
+import { InvoiceDetailRoute_invoice$key } from "__generated__/InvoiceDetailRoute_invoice.graphql"
+import { InvoiceLineItems } from "Apps/Invoice/Components/InvoiceLineItems"
+import { InvoicePayments } from "Apps/Invoice/Components/InvoicePayments"
+import { graphql, useFragment } from "react-relay"
+import { RouterLink } from "System/Components/RouterLink"
+import { useRouter } from "System/Hooks/useRouter"
+
+interface InvoiceDetailRouteProps {
+ invoice: InvoiceDetailRoute_invoice$key
+}
+
+export const InvoiceDetailRoute: React.FC = ({
+ invoice,
+}) => {
+ const data = useFragment(InvoiceDetailRouteFragment, invoice)
+
+ const { name, email, state, payments, externalNote, remaining } = data
+
+ const hasSuccessfulPayments =
+ payments.filter(({ successful }) => successful).length > 0
+
+ const isPaid = state === "PAID"
+ const { match } = useRouter()
+ const token = match.params.token
+ const paymentRoute = `/invoice/${token}/payment`
+
+ return (
+ <>
+ }>
+
+
+
+ FROM
+
+ Artsy
+
+ 401 Broadway, 25th Floor
+ New York, NY 10013
+
+
+
+
+ TO
+
+
+ Name: {name}
+
+
+
+ Email: {email}
+
+
+
+
+
+
+ {hasSuccessfulPayments && (
+ <>
+
+ >
+ )}
+
+
+ {externalNote && {externalNote}}
+
+ {remaining}
+
+
+
+
+ {!isPaid && (
+
+
+
+
+
+ )}
+ >
+ )
+}
+
+const InvoiceDetailRouteFragment = graphql`
+ fragment InvoiceDetailRoute_invoice on Invoice {
+ name
+ email
+ state
+
+ payments {
+ successful
+ }
+
+ externalNote
+ remaining(precision: 2)
+
+ ...InvoiceLineItems_invoice
+ ...InvoicePayments_invoice
+ }
+`
diff --git a/src/Apps/Invoice/Routes/InvoicePaymentRoute.tsx b/src/Apps/Invoice/Routes/InvoicePaymentRoute.tsx
new file mode 100644
index 00000000000..4122cd00fcb
--- /dev/null
+++ b/src/Apps/Invoice/Routes/InvoicePaymentRoute.tsx
@@ -0,0 +1,44 @@
+import { Box, Text } from "@artsy/palette"
+import { InvoicePaymentRoute_invoice$key } from "__generated__/InvoicePaymentRoute_invoice.graphql"
+import { InvoicePaymentForm } from "Apps/Invoice/Components/InvoicePaymentForm"
+import { CreditCardInputProvider } from "Components/CreditCardInput"
+import { graphql, useFragment } from "react-relay"
+import { useRouter } from "System/Hooks/useRouter"
+
+interface InvoicePaymentRouteProps {
+ invoice: InvoicePaymentRoute_invoice$key
+}
+
+export const InvoicePaymentRoute: React.FC = ({
+ invoice,
+}) => {
+ const data = useFragment(InvoicePaymentRouteFragment, invoice)
+
+ const { remaining, internalID, remainingMinor } = data
+ const { match } = useRouter()
+ const token = match.params.token
+
+ return (
+
+
+ Make a payment: {remaining}
+
+
+
+
+
+
+ )
+}
+
+const InvoicePaymentRouteFragment = graphql`
+ fragment InvoicePaymentRoute_invoice on Invoice {
+ remaining(precision: 2)
+ internalID
+ remainingMinor
+ }
+`
diff --git a/src/Apps/Invoice/invoiceRoutes.tsx b/src/Apps/Invoice/invoiceRoutes.tsx
new file mode 100644
index 00000000000..671e969c8d7
--- /dev/null
+++ b/src/Apps/Invoice/invoiceRoutes.tsx
@@ -0,0 +1,79 @@
+import loadable from "@loadable/component"
+import { graphql } from "react-relay"
+import { RouteProps } from "System/Router/Route"
+
+const InvoiceApp = loadable(
+ () => import(/* webpackChunkName: "invoiceBundle" */ "./InvoiceApp"),
+ {
+ resolveComponent: component => component.InvoiceApp,
+ }
+)
+
+const InvoiceDetailRoute = loadable(
+ () =>
+ import(
+ /* webpackChunkName: "invoiceBundle" */ "./Routes/InvoiceDetailRoute"
+ ),
+ {
+ resolveComponent: component => component.InvoiceDetailRoute,
+ }
+)
+
+const InvoicePaymentRoute = loadable(
+ () =>
+ import(
+ /* webpackChunkName: "invoiceBundle" */ "./Routes/InvoicePaymentRoute"
+ ),
+ {
+ resolveComponent: component => component.InvoicePaymentRoute,
+ }
+)
+
+export const invoiceRoutes: RouteProps[] = [
+ {
+ path: "/invoice/:token",
+ getComponent: () => InvoiceApp,
+ onClientSideRender: () => {
+ InvoiceApp.preload()
+ },
+ query: graphql`
+ query invoiceRoutes_InvoiceQuery($token: String!) {
+ invoice(token: $token) {
+ ...InvoiceApp_invoice
+ }
+ }
+ `,
+ children: [
+ {
+ path: "",
+ getComponent: () => InvoiceDetailRoute,
+ onClientSideRender: () => {
+ InvoiceDetailRoute.preload()
+ },
+ query: graphql`
+ query invoiceRoutes_InvoiceDetailQuery($token: String!) {
+ invoice(token: $token) {
+ ...InvoiceDetailRoute_invoice
+ }
+ }
+ `,
+ cacheConfig: { force: true },
+ },
+
+ {
+ path: "payment",
+ getComponent: () => InvoicePaymentRoute,
+ onClientSideRender: () => {
+ InvoicePaymentRoute.preload()
+ },
+ query: graphql`
+ query invoiceRoutes_InvoicePaymentQuery($token: String!) {
+ invoice(token: $token) {
+ ...InvoicePaymentRoute_invoice
+ }
+ }
+ `,
+ },
+ ],
+ },
+]
diff --git a/src/__generated__/InvoiceApp_invoice.graphql.ts b/src/__generated__/InvoiceApp_invoice.graphql.ts
new file mode 100644
index 00000000000..c0d9f0cb28e
--- /dev/null
+++ b/src/__generated__/InvoiceApp_invoice.graphql.ts
@@ -0,0 +1,56 @@
+/**
+ * @generated SignedSource<<6870df65d15bfe29ff90b78dcc51ea82>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { Fragment, ReaderFragment } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type InvoiceApp_invoice$data = {
+ readonly number: string;
+ readonly readyAt: string | null | undefined;
+ readonly " $fragmentType": "InvoiceApp_invoice";
+};
+export type InvoiceApp_invoice$key = {
+ readonly " $data"?: InvoiceApp_invoice$data;
+ readonly " $fragmentSpreads": FragmentRefs<"InvoiceApp_invoice">;
+};
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "InvoiceApp_invoice",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "number",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "format",
+ "value": "MMM D, YYYY"
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "readyAt",
+ "storageKey": "readyAt(format:\"MMM D, YYYY\")"
+ }
+ ],
+ "type": "Invoice",
+ "abstractKey": null
+};
+
+(node as any).hash = "ee1271afa542a1df6d58fa2d3a7edda5";
+
+export default node;
diff --git a/src/__generated__/InvoiceDetailRoute_invoice.graphql.ts b/src/__generated__/InvoiceDetailRoute_invoice.graphql.ts
new file mode 100644
index 00000000000..55d0ca8708f
--- /dev/null
+++ b/src/__generated__/InvoiceDetailRoute_invoice.graphql.ts
@@ -0,0 +1,113 @@
+/**
+ * @generated SignedSource<<9bbe210d85fc8192b0ba37a76cb58162>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { Fragment, ReaderFragment } from 'relay-runtime';
+export type InvoiceState = "CANCELED" | "DRAFT" | "PAID" | "READY" | "%future added value";
+import { FragmentRefs } from "relay-runtime";
+export type InvoiceDetailRoute_invoice$data = {
+ readonly email: string | null | undefined;
+ readonly externalNote: string | null | undefined;
+ readonly name: string | null | undefined;
+ readonly payments: ReadonlyArray<{
+ readonly successful: boolean;
+ }>;
+ readonly remaining: string | null | undefined;
+ readonly state: InvoiceState;
+ readonly " $fragmentSpreads": FragmentRefs<"InvoiceLineItems_invoice" | "InvoicePayments_invoice">;
+ readonly " $fragmentType": "InvoiceDetailRoute_invoice";
+};
+export type InvoiceDetailRoute_invoice$key = {
+ readonly " $data"?: InvoiceDetailRoute_invoice$data;
+ readonly " $fragmentSpreads": FragmentRefs<"InvoiceDetailRoute_invoice">;
+};
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "InvoiceDetailRoute_invoice",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "name",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "email",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "state",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "InvoicePayment",
+ "kind": "LinkedField",
+ "name": "payments",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "successful",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "externalNote",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "precision",
+ "value": 2
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "remaining",
+ "storageKey": "remaining(precision:2)"
+ },
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "InvoiceLineItems_invoice"
+ },
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "InvoicePayments_invoice"
+ }
+ ],
+ "type": "Invoice",
+ "abstractKey": null
+};
+
+(node as any).hash = "213d0a23e701bdfdd8ef4ffb3293313d";
+
+export default node;
diff --git a/src/__generated__/InvoiceLineItems_invoice.graphql.ts b/src/__generated__/InvoiceLineItems_invoice.graphql.ts
new file mode 100644
index 00000000000..2e210175d70
--- /dev/null
+++ b/src/__generated__/InvoiceLineItems_invoice.graphql.ts
@@ -0,0 +1,69 @@
+/**
+ * @generated SignedSource<<7fe51c611f81107e575a050701d99219>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { Fragment, ReaderFragment } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type InvoiceLineItems_invoice$data = {
+ readonly lineItems: ReadonlyArray<{
+ readonly amount: string | null | undefined;
+ readonly description: string;
+ }>;
+ readonly " $fragmentType": "InvoiceLineItems_invoice";
+};
+export type InvoiceLineItems_invoice$key = {
+ readonly " $data"?: InvoiceLineItems_invoice$data;
+ readonly " $fragmentSpreads": FragmentRefs<"InvoiceLineItems_invoice">;
+};
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "InvoiceLineItems_invoice",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "InvoiceLineItem",
+ "kind": "LinkedField",
+ "name": "lineItems",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "description",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "precision",
+ "value": 2
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "amount",
+ "storageKey": "amount(precision:2)"
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Invoice",
+ "abstractKey": null
+};
+
+(node as any).hash = "a99daa90c2adba129b513e3fdc252924";
+
+export default node;
diff --git a/src/__generated__/InvoicePaymentRoute_invoice.graphql.ts b/src/__generated__/InvoicePaymentRoute_invoice.graphql.ts
new file mode 100644
index 00000000000..880f43af4a9
--- /dev/null
+++ b/src/__generated__/InvoicePaymentRoute_invoice.graphql.ts
@@ -0,0 +1,64 @@
+/**
+ * @generated SignedSource<<1b598c9663dfe36fbd6b62c406707e62>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { Fragment, ReaderFragment } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type InvoicePaymentRoute_invoice$data = {
+ readonly internalID: string;
+ readonly remaining: string | null | undefined;
+ readonly remainingMinor: number;
+ readonly " $fragmentType": "InvoicePaymentRoute_invoice";
+};
+export type InvoicePaymentRoute_invoice$key = {
+ readonly " $data"?: InvoicePaymentRoute_invoice$data;
+ readonly " $fragmentSpreads": FragmentRefs<"InvoicePaymentRoute_invoice">;
+};
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "InvoicePaymentRoute_invoice",
+ "selections": [
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "precision",
+ "value": 2
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "remaining",
+ "storageKey": "remaining(precision:2)"
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "internalID",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "remainingMinor",
+ "storageKey": null
+ }
+ ],
+ "type": "Invoice",
+ "abstractKey": null
+};
+
+(node as any).hash = "dd89c4ffd0c09a71a3e0c18d5128d57c";
+
+export default node;
diff --git a/src/__generated__/InvoicePayments_invoice.graphql.ts b/src/__generated__/InvoicePayments_invoice.graphql.ts
new file mode 100644
index 00000000000..700d8d3dfc2
--- /dev/null
+++ b/src/__generated__/InvoicePayments_invoice.graphql.ts
@@ -0,0 +1,120 @@
+/**
+ * @generated SignedSource<>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { Fragment, ReaderFragment } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type InvoicePayments_invoice$data = {
+ readonly payments: ReadonlyArray<{
+ readonly amount: string | null | undefined;
+ readonly createdAt: string | null | undefined;
+ readonly creditCard: {
+ readonly brand: string;
+ readonly lastDigits: string;
+ } | null | undefined;
+ readonly id: string;
+ readonly successful: boolean;
+ }>;
+ readonly " $fragmentType": "InvoicePayments_invoice";
+};
+export type InvoicePayments_invoice$key = {
+ readonly " $data"?: InvoicePayments_invoice$data;
+ readonly " $fragmentSpreads": FragmentRefs<"InvoicePayments_invoice">;
+};
+
+const node: ReaderFragment = {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "InvoicePayments_invoice",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "InvoicePayment",
+ "kind": "LinkedField",
+ "name": "payments",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "successful",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "format",
+ "value": "MMM D, YYYY"
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": "createdAt(format:\"MMM D, YYYY\")"
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "precision",
+ "value": 2
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "amount",
+ "storageKey": "amount(precision:2)"
+ },
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "CreditCard",
+ "kind": "LinkedField",
+ "name": "creditCard",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "brand",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "lastDigits",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Invoice",
+ "abstractKey": null
+};
+
+(node as any).hash = "93f07c74b980a580fdba33d0bd598938";
+
+export default node;
diff --git a/src/__generated__/invoiceRoutes_InvoiceDetailQuery.graphql.ts b/src/__generated__/invoiceRoutes_InvoiceDetailQuery.graphql.ts
new file mode 100644
index 00000000000..b81d79159d5
--- /dev/null
+++ b/src/__generated__/invoiceRoutes_InvoiceDetailQuery.graphql.ts
@@ -0,0 +1,236 @@
+/**
+ * @generated SignedSource<<4853612b420100dcf5341a5e02d9a2ef>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest, Query } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type invoiceRoutes_InvoiceDetailQuery$variables = {
+ token: string;
+};
+export type invoiceRoutes_InvoiceDetailQuery$data = {
+ readonly invoice: {
+ readonly " $fragmentSpreads": FragmentRefs<"InvoiceDetailRoute_invoice">;
+ } | null | undefined;
+};
+export type invoiceRoutes_InvoiceDetailQuery = {
+ response: invoiceRoutes_InvoiceDetailQuery$data;
+ variables: invoiceRoutes_InvoiceDetailQuery$variables;
+};
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "defaultValue": null,
+ "kind": "LocalArgument",
+ "name": "token"
+ }
+],
+v1 = [
+ {
+ "kind": "Variable",
+ "name": "token",
+ "variableName": "token"
+ }
+],
+v2 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+},
+v3 = [
+ {
+ "kind": "Literal",
+ "name": "precision",
+ "value": 2
+ }
+],
+v4 = {
+ "alias": null,
+ "args": (v3/*: any*/),
+ "kind": "ScalarField",
+ "name": "amount",
+ "storageKey": "amount(precision:2)"
+};
+return {
+ "fragment": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "invoiceRoutes_InvoiceDetailQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "Invoice",
+ "kind": "LinkedField",
+ "name": "invoice",
+ "plural": false,
+ "selections": [
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "InvoiceDetailRoute_invoice"
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Operation",
+ "name": "invoiceRoutes_InvoiceDetailQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "Invoice",
+ "kind": "LinkedField",
+ "name": "invoice",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "name",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "email",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "state",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "InvoicePayment",
+ "kind": "LinkedField",
+ "name": "payments",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "successful",
+ "storageKey": null
+ },
+ (v2/*: any*/),
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "format",
+ "value": "MMM D, YYYY"
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": "createdAt(format:\"MMM D, YYYY\")"
+ },
+ (v4/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "CreditCard",
+ "kind": "LinkedField",
+ "name": "creditCard",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "brand",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "lastDigits",
+ "storageKey": null
+ },
+ (v2/*: any*/)
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "externalNote",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": (v3/*: any*/),
+ "kind": "ScalarField",
+ "name": "remaining",
+ "storageKey": "remaining(precision:2)"
+ },
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "InvoiceLineItem",
+ "kind": "LinkedField",
+ "name": "lineItems",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "description",
+ "storageKey": null
+ },
+ (v4/*: any*/),
+ (v2/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v2/*: any*/)
+ ],
+ "storageKey": null
+ }
+ ]
+ },
+ "params": {
+ "cacheID": "2b9ce39a17afe7ac05b3615cf29c85b3",
+ "id": null,
+ "metadata": {},
+ "name": "invoiceRoutes_InvoiceDetailQuery",
+ "operationKind": "query",
+ "text": "query invoiceRoutes_InvoiceDetailQuery(\n $token: String!\n) {\n invoice(token: $token) {\n ...InvoiceDetailRoute_invoice\n id\n }\n}\n\nfragment InvoiceDetailRoute_invoice on Invoice {\n name\n email\n state\n payments {\n successful\n id\n }\n externalNote\n remaining(precision: 2)\n ...InvoiceLineItems_invoice\n ...InvoicePayments_invoice\n}\n\nfragment InvoiceLineItems_invoice on Invoice {\n lineItems {\n description\n amount(precision: 2)\n id\n }\n}\n\nfragment InvoicePayments_invoice on Invoice {\n payments {\n id\n successful\n createdAt(format: \"MMM D, YYYY\")\n amount(precision: 2)\n creditCard {\n brand\n lastDigits\n id\n }\n }\n}\n"
+ }
+};
+})();
+
+(node as any).hash = "ee553be3d159a34d9753a955455a4a23";
+
+export default node;
diff --git a/src/__generated__/invoiceRoutes_InvoicePaymentQuery.graphql.ts b/src/__generated__/invoiceRoutes_InvoicePaymentQuery.graphql.ts
new file mode 100644
index 00000000000..b1a3f6aa8ad
--- /dev/null
+++ b/src/__generated__/invoiceRoutes_InvoicePaymentQuery.graphql.ts
@@ -0,0 +1,134 @@
+/**
+ * @generated SignedSource<>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest, Query } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type invoiceRoutes_InvoicePaymentQuery$variables = {
+ token: string;
+};
+export type invoiceRoutes_InvoicePaymentQuery$data = {
+ readonly invoice: {
+ readonly " $fragmentSpreads": FragmentRefs<"InvoicePaymentRoute_invoice">;
+ } | null | undefined;
+};
+export type invoiceRoutes_InvoicePaymentQuery = {
+ response: invoiceRoutes_InvoicePaymentQuery$data;
+ variables: invoiceRoutes_InvoicePaymentQuery$variables;
+};
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "defaultValue": null,
+ "kind": "LocalArgument",
+ "name": "token"
+ }
+],
+v1 = [
+ {
+ "kind": "Variable",
+ "name": "token",
+ "variableName": "token"
+ }
+];
+return {
+ "fragment": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "invoiceRoutes_InvoicePaymentQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "Invoice",
+ "kind": "LinkedField",
+ "name": "invoice",
+ "plural": false,
+ "selections": [
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "InvoicePaymentRoute_invoice"
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Operation",
+ "name": "invoiceRoutes_InvoicePaymentQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "Invoice",
+ "kind": "LinkedField",
+ "name": "invoice",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "precision",
+ "value": 2
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "remaining",
+ "storageKey": "remaining(precision:2)"
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "internalID",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "remainingMinor",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ]
+ },
+ "params": {
+ "cacheID": "342fb5e595a8161a3ed3308adb7b6916",
+ "id": null,
+ "metadata": {},
+ "name": "invoiceRoutes_InvoicePaymentQuery",
+ "operationKind": "query",
+ "text": "query invoiceRoutes_InvoicePaymentQuery(\n $token: String!\n) {\n invoice(token: $token) {\n ...InvoicePaymentRoute_invoice\n id\n }\n}\n\nfragment InvoicePaymentRoute_invoice on Invoice {\n remaining(precision: 2)\n internalID\n remainingMinor\n}\n"
+ }
+};
+})();
+
+(node as any).hash = "46da36776fb731441a3efcef9a8190ec";
+
+export default node;
diff --git a/src/__generated__/invoiceRoutes_InvoiceQuery.graphql.ts b/src/__generated__/invoiceRoutes_InvoiceQuery.graphql.ts
new file mode 100644
index 00000000000..3855803c572
--- /dev/null
+++ b/src/__generated__/invoiceRoutes_InvoiceQuery.graphql.ts
@@ -0,0 +1,127 @@
+/**
+ * @generated SignedSource<<7a54c7deb80c7fac1b6b660d98921d1e>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest, Query } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type invoiceRoutes_InvoiceQuery$variables = {
+ token: string;
+};
+export type invoiceRoutes_InvoiceQuery$data = {
+ readonly invoice: {
+ readonly " $fragmentSpreads": FragmentRefs<"InvoiceApp_invoice">;
+ } | null | undefined;
+};
+export type invoiceRoutes_InvoiceQuery = {
+ response: invoiceRoutes_InvoiceQuery$data;
+ variables: invoiceRoutes_InvoiceQuery$variables;
+};
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "defaultValue": null,
+ "kind": "LocalArgument",
+ "name": "token"
+ }
+],
+v1 = [
+ {
+ "kind": "Variable",
+ "name": "token",
+ "variableName": "token"
+ }
+];
+return {
+ "fragment": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "invoiceRoutes_InvoiceQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "Invoice",
+ "kind": "LinkedField",
+ "name": "invoice",
+ "plural": false,
+ "selections": [
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "InvoiceApp_invoice"
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Operation",
+ "name": "invoiceRoutes_InvoiceQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "Invoice",
+ "kind": "LinkedField",
+ "name": "invoice",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "number",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "format",
+ "value": "MMM D, YYYY"
+ }
+ ],
+ "kind": "ScalarField",
+ "name": "readyAt",
+ "storageKey": "readyAt(format:\"MMM D, YYYY\")"
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ]
+ },
+ "params": {
+ "cacheID": "b34dab2604f8f34105035285a3dc36ad",
+ "id": null,
+ "metadata": {},
+ "name": "invoiceRoutes_InvoiceQuery",
+ "operationKind": "query",
+ "text": "query invoiceRoutes_InvoiceQuery(\n $token: String!\n) {\n invoice(token: $token) {\n ...InvoiceApp_invoice\n id\n }\n}\n\nfragment InvoiceApp_invoice on Invoice {\n number\n readyAt(format: \"MMM D, YYYY\")\n}\n"
+ }
+};
+})();
+
+(node as any).hash = "22f7db6b7486ac49dafcd58802edaf42";
+
+export default node;
diff --git a/src/__generated__/useMakeInvoicePaymentMutation.graphql.ts b/src/__generated__/useMakeInvoicePaymentMutation.graphql.ts
new file mode 100644
index 00000000000..452cfe17c90
--- /dev/null
+++ b/src/__generated__/useMakeInvoicePaymentMutation.graphql.ts
@@ -0,0 +1,166 @@
+/**
+ * @generated SignedSource<<41eb028e2f86698e979ade9779094e69>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest, Mutation } from 'relay-runtime';
+export type CreateInvoicePaymentInput = {
+ amountMinor: number;
+ clientMutationId?: string | null | undefined;
+ creditCardToken: string;
+ invoiceID: string;
+ invoiceToken: string;
+ provider: string;
+};
+export type useMakeInvoicePaymentMutation$variables = {
+ input: CreateInvoicePaymentInput;
+};
+export type useMakeInvoicePaymentMutation$data = {
+ readonly createInvoicePayment: {
+ readonly __typename: "CreateInvoicePaymentPayload";
+ readonly responseOrError: {
+ readonly mutationError?: {
+ readonly message: string;
+ } | null | undefined;
+ } | null | undefined;
+ } | null | undefined;
+};
+export type useMakeInvoicePaymentMutation = {
+ response: useMakeInvoicePaymentMutation$data;
+ variables: useMakeInvoicePaymentMutation$variables;
+};
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "defaultValue": null,
+ "kind": "LocalArgument",
+ "name": "input"
+ }
+],
+v1 = [
+ {
+ "kind": "Variable",
+ "name": "input",
+ "variableName": "input"
+ }
+],
+v2 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "__typename",
+ "storageKey": null
+},
+v3 = {
+ "kind": "InlineFragment",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "GravityMutationError",
+ "kind": "LinkedField",
+ "name": "mutationError",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "message",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "CreateInvoicePaymentFailure",
+ "abstractKey": null
+};
+return {
+ "fragment": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "useMakeInvoicePaymentMutation",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "CreateInvoicePaymentPayload",
+ "kind": "LinkedField",
+ "name": "createInvoicePayment",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": null,
+ "kind": "LinkedField",
+ "name": "responseOrError",
+ "plural": false,
+ "selections": [
+ (v3/*: any*/)
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Mutation",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Operation",
+ "name": "useMakeInvoicePaymentMutation",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": "CreateInvoicePaymentPayload",
+ "kind": "LinkedField",
+ "name": "createInvoicePayment",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": null,
+ "kind": "LinkedField",
+ "name": "responseOrError",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ (v3/*: any*/)
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ]
+ },
+ "params": {
+ "cacheID": "76aec82acae55653903cd0d5d009bc36",
+ "id": null,
+ "metadata": {},
+ "name": "useMakeInvoicePaymentMutation",
+ "operationKind": "mutation",
+ "text": "mutation useMakeInvoicePaymentMutation(\n $input: CreateInvoicePaymentInput!\n) {\n createInvoicePayment(input: $input) {\n __typename\n responseOrError {\n __typename\n ... on CreateInvoicePaymentFailure {\n mutationError {\n message\n }\n }\n }\n }\n}\n"
+ }
+};
+})();
+
+(node as any).hash = "eb46640c0326ab58cf0482b6b1821af5";
+
+export default node;
diff --git a/src/routes.tsx b/src/routes.tsx
index dc02c34923b..8a3afc16672 100644
--- a/src/routes.tsx
+++ b/src/routes.tsx
@@ -25,6 +25,7 @@ import { geneRoutes } from "Apps/Gene/geneRoutes"
import { homeRoutes } from "Apps/Home/homeRoutes"
import { identityVerificationRoutes } from "Apps/IdentityVerification/identityVerificationRoutes"
import { institutionPartnershipsRoutes } from "Apps/InstitutionPartnerships/institutionPartnershipsRoutes"
+import { invoiceRoutes } from "Apps/Invoice/invoiceRoutes"
import { jobsRoutes } from "Apps/Jobs/jobsRoutes"
import { marketingRoutes } from "Apps/Marketing/marketingRoutes"
import { myCollectionRoutes } from "Apps/MyCollection/myCollectionRoutes"
@@ -93,6 +94,7 @@ const ROUTES = buildAppRoutes([
homeRoutes,
identityVerificationRoutes,
institutionPartnershipsRoutes,
+ invoiceRoutes,
jobsRoutes,
marketingRoutes,
myCollectionRoutes,