diff --git a/.changeset/cold-owls-attack.md b/.changeset/cold-owls-attack.md new file mode 100644 index 00000000..1b19ce30 --- /dev/null +++ b/.changeset/cold-owls-attack.md @@ -0,0 +1,5 @@ +--- +'@interledger/open-payments': major +--- + +Removed externalRef and description fields from incoming and outgoing payments. metadata field should be used to store these fields instead. diff --git a/openapi/resource-server.yaml b/openapi/resource-server.yaml index 6017b559..3520ec6d 100644 --- a/openapi/resource-server.yaml +++ b/openapi/resource-server.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: Open Payments - version: '1.0' + version: '1.1' license: name: Apache 2.0 identifier: Apache-2.0 @@ -167,7 +167,6 @@ paths: assetScale: 2 completed: false expiresAt: '2022-02-03T23:20:50.52Z' - externalRef: INV2022-02-0137 metadata: { externalRef: 'INV2022-02-0137' } ilpStreamConnection: id: 'https://openpayments.guide/connections/ff394f02-7b7b-45e2-b645-51d04e7c345c' @@ -195,14 +194,6 @@ paths: description: The date and time when payments into the incoming payment must no longer be accepted. format: date-time writeOnly: true - description: - type: string - description: Human readable description of the incoming payment that will be visible to the account holder. - deprecated: true - externalRef: - type: string - description: A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. (Optional) - deprecated: true metadata: type: object additionalProperties: true @@ -215,7 +206,6 @@ paths: value: '2500' assetCode: USD assetScale: 2 - externalRef: INV2022-02-0137 metadata: { externalRef: 'INV2022-02-0137' } description: |- A subset of the incoming payments schema is accepted as input to create a new incoming payment. @@ -229,7 +219,7 @@ paths: All of the input parameters are _optional_. - For example, the client can specify an invoice number as the `externalRef` property of the **incoming payment** and this can be shared with the account holder to assist with reconciliation. + For example, the client could use the `metadata` property to store an external reference on the **incoming payment** and this can be shared with the account holder to assist with reconciliation. If `incomingAmount` is specified and the total received using the payment details equals or exceeds the specified `incomingAmount`, then the receiving Account Servicing Entity MUST reject any further payments and set `completed` to `true`. @@ -277,8 +267,6 @@ paths: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'Hi Mo, this is for the cappuccino I bought for you the other day.' - externalRef: Coffee w/ Mo on 10 March 22 metadata: { description: 'Hi Mo, this is for the cappuccino I bought for you the other day.', @@ -295,7 +283,10 @@ paths: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'I love your website, Alice! Thanks for the great content' + metadata: + { + description: 'I love your website, Alice! Thanks for the great content' + } completed: false backward pagination: value: @@ -316,7 +307,10 @@ paths: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'I love your website, Alice! Thanks for the great content' + metadata: + { + description: 'I love your website, Alice! Thanks for the great content' + } - id: 'https://openpayments.guide/alice/incoming-payments/016da9d5-c9a4-4c80-a354-86b915a04ff8' paymentPointer: 'https://openpayments.guide/alice/' incomingAmount: @@ -332,8 +326,6 @@ paths: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'Hi Mo, this is for the cappuccino I bought for you the other day.' - externalRef: Coffee w/ Mo on 10 March 22 metadata: { description: 'Hi Mo, this is for the cappuccino I bought for you the other day.', @@ -384,7 +376,7 @@ paths: value: '0' assetCode: USD assetScale: 2 - description: Thank you for the shoes. + metadata: { description: Thank you for the shoes. } createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' '401': @@ -398,7 +390,6 @@ paths: Create an outgoing payment based on a quote: value: quoteId: 'https://openpayments.guide/alice/quotes/ab03296b-0c8b-4776-b94e-7ee27d868d4d' - externalRef: INV2022-02-0137 metadata: { externalRef: 'INV2022-02-0137' } schema: type: object @@ -407,14 +398,6 @@ paths: type: string format: uri description: The URL of the quote defining this payment's amounts. - description: - type: string - description: Human readable description of the outgoing payment that will be visible to the account holder and shared with the receiver. - deprecated: true - externalRef: - type: string - description: A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. (Optional) - deprecated: true metadata: type: object additionalProperties: true @@ -479,8 +462,6 @@ paths: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: APlusVideo subscription - externalRef: 'customer: 847458475' metadata: { description: 'APlusVideo subscription', @@ -504,8 +485,6 @@ paths: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: Thank you for your purchase at ShoeShop! - externalRef: INV2022-8943756 metadata: { description: 'Thank you for your purchase at ShoeShop!', @@ -537,8 +516,6 @@ paths: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: Thank you for your purchase at ShoeShop! - externalRef: INV2022-8943756 metadata: { description: 'Thank you for your purchase at ShoeShop!', @@ -562,8 +539,6 @@ paths: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: APlusVideo subscription - externalRef: 'customer: 847458475' metadata: { description: 'APlusVideo subscription', @@ -707,8 +682,6 @@ paths: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: Thanks for the flowers! - externalRef: INV-12876 metadata: { description: 'Thanks for the flowers!', @@ -763,8 +736,6 @@ paths: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'Hi Mo, this is for the cappuccino I bought for you the other day.' - externalRef: Coffee w/ Mo on 10 March 22 metadata: { description: 'Hi Mo, this is for the cappuccino I bought for you the other day.', @@ -819,8 +790,6 @@ paths: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: Thanks for the flowers! - externalRef: INV-12876 metadata: { description: 'Thanks for the flowers!', @@ -992,8 +961,6 @@ components: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'Hi Mo, this is for the cappuccino I bought for you the other day.' - externalRef: Coffee w/ Mo on 10 March 22 metadata: { description: 'Hi Mo, this is for the cappuccino I bought for you the other day.', @@ -1037,14 +1004,6 @@ components: type: string description: The date and time when payments under this incoming payment will no longer be accepted. format: date-time - description: - type: string - description: Human readable description of the incoming payment that will be visible to the account holder. - deprecated: true - externalRef: - type: string - description: A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. - deprecated: true metadata: type: object additionalProperties: true @@ -1083,8 +1042,6 @@ components: expiresAt: '2022-04-12T23:20:50.52Z' createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: 'Hi Mo, this is for the cappuccino I bought for you the other day.' - externalRef: Coffee w/ Mo on 10 March 22 metadata: { description: 'Hi Mo, this is for the cappuccino I bought for you the other day.', @@ -1153,8 +1110,6 @@ components: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: APlusVideo subscription - externalRef: 'customer: 847458475' metadata: { description: 'APlusVideo subscription', @@ -1174,8 +1129,6 @@ components: assetScale: 2 createdAt: '2022-03-12T23:20:50.52Z' updatedAt: '2022-04-01T10:24:36.11Z' - description: Thank you for your purchase at ShoeShop! - externalRef: INV2022-8943756 metadata: { description: 'Thank you for your purchase at ShoeShop!', @@ -1213,14 +1166,6 @@ components: sentAmount: description: The total amount that has been sent under this outgoing payment. $ref: ./schemas.yaml#/components/schemas/amount - description: - type: string - description: Human readable description of the outgoing payment that will be visible to the account holder and shared with the receiver. - deprecated: true - externalRef: - type: string - description: A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. (Optional) - deprecated: true metadata: type: object additionalProperties: true diff --git a/packages/open-payments/README.md b/packages/open-payments/README.md index 2a1b80ed..7a82420e 100644 --- a/packages/open-payments/README.md +++ b/packages/open-payments/README.md @@ -144,9 +144,10 @@ const incomingPayment = await client.incomingPayment.create( assetScale: 2, value: '5000' }, - description: 'Purchase at Shoe Shop', - externalRef: '#INV2022-8363828' - metadata: '{"externalRef": "#INV2022-8363828", "description": "Purchase at Shoe Shop"}', + metadata: { + externalRef: '#INV2022-8363828', + description: 'Purchase at Shoe Shop' + } } ) ``` diff --git a/packages/open-payments/src/client/incoming-payment.test.ts b/packages/open-payments/src/client/incoming-payment.test.ts index 11ff15c8..a3ba496b 100644 --- a/packages/open-payments/src/client/incoming-payment.test.ts +++ b/packages/open-payments/src/client/incoming-payment.test.ts @@ -125,23 +125,15 @@ describe('incoming-payment', (): void => { describe('createIncomingPayment', (): void => { test.each` - incomingAmount | expiresAt | description | externalRef | metadata - ${undefined} | ${undefined} | ${undefined} | ${undefined} | ${undefined} - ${{ assetCode: 'USD', assetScale: 2, value: '10' }} | ${new Date(Date.now() + 60_000).toISOString()} | ${'Invoice'} | ${'#INV-1'} | ${'{"description": "Invoice", "externalRef": "#INV-1"}'} + incomingAmount | expiresAt | metadata + ${undefined} | ${undefined} | ${undefined} + ${{ assetCode: 'USD', assetScale: 2, value: '10' }} | ${new Date(Date.now() + 60_000).toISOString()} | ${{ description: 'Invoice', externalRef: '#INV-1' }} `( 'returns the incoming payment on success', - async ({ - incomingAmount, - expiresAt, - description, - externalRef, - metadata - }): Promise => { + async ({ incomingAmount, expiresAt, metadata }): Promise => { const incomingPayment = mockIncomingPaymentWithConnection({ incomingAmount, expiresAt, - description, - externalRef, metadata }) @@ -156,8 +148,6 @@ describe('incoming-payment', (): void => { { incomingAmount, expiresAt, - description, - externalRef, metadata } ) diff --git a/packages/open-payments/src/client/outgoing-payment.test.ts b/packages/open-payments/src/client/outgoing-payment.test.ts index a2aa8457..8c104745 100644 --- a/packages/open-payments/src/client/outgoing-payment.test.ts +++ b/packages/open-payments/src/client/outgoing-payment.test.ts @@ -260,41 +260,34 @@ describe('outgoing-payment', (): void => { const quoteId = `${paymentPointer}/quotes/${uuid()}` test.each` - description | externalRef | metadata - ${'Some description'} | ${'#INV-1'} | ${'{"description": "Some description", "externalRef": "#INV-1"}'} - ${undefined} | ${undefined} | ${undefined} - `( - 'creates outgoing payment', - async ({ description, externalRef, metadata }): Promise => { - const outgoingPayment = mockOutgoingPayment({ - quoteId, - description, - externalRef, - metadata - }) + metadata + ${{ description: 'Some description', externalRef: '#INV-1' }} + ${undefined} + `('creates outgoing payment', async ({ metadata }): Promise => { + const outgoingPayment = mockOutgoingPayment({ + quoteId, + metadata + }) - const scope = nock(paymentPointer) - .post('/outgoing-payments') - .reply(200, outgoingPayment) + const scope = nock(paymentPointer) + .post('/outgoing-payments') + .reply(200, outgoingPayment) - const result = await createOutgoingPayment( - { axiosInstance, logger }, - { - paymentPointer, - accessToken: 'accessToken' - }, - openApiValidators.successfulValidator, - { - quoteId, - description, - externalRef, - metadata - } - ) - expect(result).toEqual(outgoingPayment) - scope.done() - } - ) + const result = await createOutgoingPayment( + { axiosInstance, logger }, + { + paymentPointer, + accessToken: 'accessToken' + }, + openApiValidators.successfulValidator, + { + quoteId, + metadata + } + ) + expect(result).toEqual(outgoingPayment) + scope.done() + }) test('throws if outgoing payment does not pass validation', async (): Promise => { const outgoingPayment = mockOutgoingPayment({ diff --git a/packages/open-payments/src/openapi/generated/resource-server-types.ts b/packages/open-payments/src/openapi/generated/resource-server-types.ts index 7963e993..9f091529 100644 --- a/packages/open-payments/src/openapi/generated/resource-server-types.ts +++ b/packages/open-payments/src/openapi/generated/resource-server-types.ts @@ -46,7 +46,7 @@ export interface paths { * * All of the input parameters are _optional_. * - * For example, the client can specify an invoice number as the `externalRef` property of the **incoming payment** and this can be shared with the account holder to assist with reconciliation. + * For example, the client could use the `metadata` property to store an external reference on the **incoming payment** and this can be shared with the account holder to assist with reconciliation. * * If `incomingAmount` is specified and the total received using the payment details equals or exceeds the specified `incomingAmount`, then the receiving Account Servicing Entity MUST reject any further payments and set `completed` to `true`. * @@ -188,16 +188,6 @@ export interface components { * @description The date and time when payments under this incoming payment will no longer be accepted. */ expiresAt?: string; - /** - * @deprecated - * @description Human readable description of the incoming payment that will be visible to the account holder. - */ - description?: string; - /** - * @deprecated - * @description A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. - */ - externalRef?: string; /** @description Additional metadata associated with the incoming payment. (Optional) */ metadata?: { [key: string]: unknown }; /** @@ -259,16 +249,6 @@ export interface components { sendAmount: external["schemas.yaml"]["components"]["schemas"]["amount"]; /** @description The total amount that has been sent under this outgoing payment. */ sentAmount: external["schemas.yaml"]["components"]["schemas"]["amount"]; - /** - * @deprecated - * @description Human readable description of the outgoing payment that will be visible to the account holder and shared with the receiver. - */ - description?: string; - /** - * @deprecated - * @description A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. (Optional) - */ - externalRef?: string; /** @description Additional metadata associated with the outgoing payment. (Optional) */ metadata?: { [key: string]: unknown }; /** @@ -454,7 +434,7 @@ export interface operations { * * All of the input parameters are _optional_. * - * For example, the client can specify an invoice number as the `externalRef` property of the **incoming payment** and this can be shared with the account holder to assist with reconciliation. + * For example, the client could use the `metadata` property to store an external reference on the **incoming payment** and this can be shared with the account holder to assist with reconciliation. * * If `incomingAmount` is specified and the total received using the payment details equals or exceeds the specified `incomingAmount`, then the receiving Account Servicing Entity MUST reject any further payments and set `completed` to `true`. * @@ -494,16 +474,6 @@ export interface operations { * @description The date and time when payments into the incoming payment must no longer be accepted. */ expiresAt?: string; - /** - * @deprecated - * @description Human readable description of the incoming payment that will be visible to the account holder. - */ - description?: string; - /** - * @deprecated - * @description A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. (Optional) - */ - externalRef?: string; /** @description Additional metadata associated with the incoming payment. (Optional) */ metadata?: { [key: string]: unknown }; }; @@ -579,16 +549,6 @@ export interface operations { * @description The URL of the quote defining this payment's amounts. */ quoteId: string; - /** - * @deprecated - * @description Human readable description of the outgoing payment that will be visible to the account holder and shared with the receiver. - */ - description?: string; - /** - * @deprecated - * @description A reference that can be used by external systems to reconcile this payment with their systems. E.g. An invoice number. (Optional) - */ - externalRef?: string; /** @description Additional metadata associated with the outgoing payment. (Optional) */ metadata?: { [key: string]: unknown }; }; diff --git a/packages/open-payments/src/test/helpers.ts b/packages/open-payments/src/test/helpers.ts index b6d599b3..8851ba0d 100644 --- a/packages/open-payments/src/test/helpers.ts +++ b/packages/open-payments/src/test/helpers.ts @@ -171,8 +171,6 @@ export const mockOutgoingPayment = ( }, quoteId: uuid(), receiver: uuid(), - description: 'some description', - externalRef: 'INV #1', metadata: { externalRef: 'INV #1', description: 'some description' }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), diff --git a/packages/openapi/src/middleware.test.ts b/packages/openapi/src/middleware.test.ts index 637fd1a4..2827385a 100644 --- a/packages/openapi/src/middleware.test.ts +++ b/packages/openapi/src/middleware.test.ts @@ -155,8 +155,6 @@ describe('OpenAPI Validator', (): void => { ${{ incomingAmount: { value: '-2', assetCode: 'USD', assetScale: 2 } }} | ${'body.incomingAmount.value must match format "uint64"'} | ${'invalid incomingAmount, value non-positive'} ${{ incomingAmount: { value: '2', assetCode: 4, assetScale: 2 } }} | ${'body.incomingAmount.assetCode must be string'} | ${'invalid incomingAmount, assetCode not string'} ${{ incomingAmount: { value: '2', assetCode: 'USD', assetScale: -2 } }} | ${'body.incomingAmount.assetScale must be >= 0'} | ${'invalid incomingAmount, assetScale negative'} - ${{ description: 123 }} | ${'body.description must be string'} | ${'invalid description'} - ${{ externalRef: 123 }} | ${'body.externalRef must be string'} | ${'invalid externalRef'} ${{ expiresAt: 'fail' }} | ${'body.expiresAt must match format "date-time"'} | ${'invalid expiresAt'} ${{ additionalProp: 'disallowed' }} | ${'body must NOT have additional properties: additionalProp'} | ${'invalid additional property'} `(