Skip to content

Commit 1eb43ae

Browse files
mkurapovoana-loleanjlielengyel-arpad85beniaminmunteanu
committed
feat: adding card-service and point-of-sale (#3715)
* feat: created the backbone for the card service (#3508) * Created the backbone for the card service * Format fix * feat: add card service to docker compose --------- Co-authored-by: Nathan Lie <[email protected]> * feat: initialize POS service (#3509) * feat(wip): pos service * Completed POS service init * Added docker files and missing scripts * Removed editor code after handling conflicts * Updated docker-compose for cloud 9 localenv and removed unnecessary telemetry command from dockerfile * Updated docker compose files for c9 and hlb * Updated ports and env var names from config * fix: install ts-node-dev, add main script to index.ts --------- Co-authored-by: Nathan Lie <[email protected]> * feat(card-service): card payments table (#3514) * migration & model for card payments * feat(pos): create merchants table (#3519) * merchants table migrations and model * typo * Docker compose fix (for slower PCs) on localenv (#3522) * fix(cards-service): add dependencies to package.json (#3530) * fix(cards-service): add dependencies to package.json * chore(cards-service): lockfile * feat: Added CardService client in rafiki backend (#3510) * feat(pos): pos card services table (#3526) * merchants table migrations and model * feat(card-service): introduce testcontainers for database and redis (#3533) * feat(card-service): add testcontainers setup * chore(cards-service): lockfile * feat(cards-service): fix test containers setup * fix(cards-service): fix type issue * feat(pos): merchants services (#3528) * merchant service * jest setup * tests * feat: Integrate Redis client in Card Service for (requestId, posServiceHost) mapping (#3524) * Integrate Redis client in Card Service for (requestId, posServiceHost) mapping * remove unused dep * prettier fix * Separate logging params from the message itself * ttl * prettier fix * Rewrite redis service tests to use testcontainers instead of mocks --------- Co-authored-by: Antoniu Neacsu <[email protected]> * feat(pos): create merchant route (#3538) * post merchants route --------- Co-authored-by: Nathan Lie <[email protected]> * feat(card-service): introduce AuditLogService (#3525) * feat(card-service): introduce AuditLogService * feat(card-service): add testcontainers setup * chore(cards-service): lockfile * fix service update method and add tests. card_payemnts migration index added * chore(cards-service): remove unnecessary app container start in tests * chore(cards-service): add uuid as a placeholder for open payments tennantId for clarity * chore(cards-service): format imports * fix(localenv): add required env vars to docker-compose (#3550) * feat(point-of-sale): POS Device service (#3548) * pos device service * Added algorithm as param on registering device, updated tests so that we check the device obj * feat(pos): RAF-1121-revoke merchant route (#3553) * feat(ci/cd): add ci jobs for testing point of sale and card-service (#3554) [CLOSES RAF-1109](https://linear.app/interledger/issue/RAF-1109/devops-cicd-github-actions-to-test-card-and-pos-service) * fix: (rafiki backend) Augment Wallet Address response with cardService field (#3552) * feat: add cardServiceUrl configuration and update related routes * feat: rename CARD_SERVICE_HOST to CARD_SERVICE_URL for consistency * fix format --------- Co-authored-by: HRadry <[email protected]> * fix(localenv): rename CARD_SERVICE_HOST to CARD_SERVICE_URL * feat(point-of-sale): added route for registering a POS device (#3555) * Route for registering a POS device * Fixed issue addressed in comments, tried to fix the port issue of jest * Changed test container port to 0, format fix * fix: typo in route * feat: bruno calls for creating merchant and registering POS device (#3558) * feat: [RAF-1083][POS Service]: Add GQL Client for Rafiki BE calls for incoming payment operations (#3546) * feat(pos): device revoke (#3560) * feat(pos): nested routing for devices, device revoke route & error handling * feat(pos-service): pos devices router and service specific error handling * feat(pos): test app now uses dynamic ports to avoid jest worker conflicts * fix(pos): fix tests * chore(pos-service): PR suggestions * fix(pos): extend error handling approach to register route in pos devices * chore(pos): remove unused knex in routes * chore(pos): rename DeviceRoutes * chore(pos): pnpm-lock * chore(pos): format * feat: added card service client to initiate a payment from pos service (#3535) * Added card service client to initiate a payment * feat(backend): Raul/raf 1095 augment outgoing payments for card (#3539) * feat(backend): add card information to outgoing payment graph ql * fix(backend): save expiry as string MM/YY * feature(backend): add mm/yy validation * fix(backend): run prittier * fix(backend): comments and set type to table name and relation * fix(backend): remove unused deps * feat(backend): add tests for outgoing payments with card details * fix(backend): fix pr comments --------- Co-authored-by: Raul Ranete <[email protected]> * feat(point-of-sale): service for obtaining walletAddress by its url from Rafiki Backend (#3578) * Added axios call to rafiki backend for getting wallet address by its url * Handled the case when cardServiceUrl may not be set on wallet address * feat(card-service): add endpoints to initiate payment and receive payment result (#3547) * feat(card-service): add endpoints to initiate payment and recieve payment result * fix: improve open api spec validation * fix: rename paymetn timeout var and comment terminal cert prop * fix: add PaymentRouteError * fix: rename env var and remove deleted prop * fix(backend): made CARD_SERVICE_URL optional (#3600) * Made CARD_SERVICE_URL optional * Created cardService container only if cardServiceUrl is set in config * Added noop card service when cardServiceUrl is not provided * Regenerated graphql * Added warning when CARD_SERVICE_URL is not set * feat(point-of-sale): POST payment route (#3597) * Payment route structure * Added routes test file * Removed some comments * Added test for unknown error * Updated graphql generated files * feat(backend): publish webhooks to POS service if applicable (#3596) * feat: created the backbone for the card service (#3508) * Created the backbone for the card service * Format fix * feat: add card service to docker compose --------- Co-authored-by: Nathan Lie <[email protected]> * feat: Integrate Redis client in Card Service for (requestId, posServiceHost) mapping (#3524) * Integrate Redis client in Card Service for (requestId, posServiceHost) mapping * remove unused dep * prettier fix * Separate logging params from the message itself * ttl * prettier fix * Rewrite redis service tests to use testcontainers instead of mocks --------- Co-authored-by: Antoniu Neacsu <[email protected]> * feat(point-of-sale): added route for registering a POS device (#3555) * Route for registering a POS device * Fixed issue addressed in comments, tried to fix the port issue of jest * Changed test container port to 0, format fix * feat(backend): publish webhooks to POS service if applicable * feat: add column to incoming payment * fix: tests * feat: add warn log * fix: better logger requirements for finalizing webhook recipients * fix: make open payments default reason for incoming payment initialization * fix: improve optional env var function * fix: warn log, better optional env, backfill migration, tests * fix: rebase bugs * chore: regenerate lockfile * chore: regenerate gql * fix: tests * fix: remove metadata; better tests * fix: build errors * fix: tests, add type file --------- Co-authored-by: oana-lolea <[email protected]> Co-authored-by: zeppelin44 <[email protected]> Co-authored-by: Antoniu Neacsu <[email protected]> * feat(point-of-sale): handle incoming payment completed webhooks from backend (#3613) * feat: created the backbone for the card service (#3508) * Created the backbone for the card service * Format fix * feat: add card service to docker compose --------- Co-authored-by: Nathan Lie <[email protected]> * feat: initialize POS service (#3509) * feat(wip): pos service * Completed POS service init * Added docker files and missing scripts * Removed editor code after handling conflicts * Updated docker-compose for cloud 9 localenv and removed unnecessary telemetry command from dockerfile * Updated docker compose files for c9 and hlb * Updated ports and env var names from config * fix: install ts-node-dev, add main script to index.ts --------- Co-authored-by: Nathan Lie <[email protected]> * feat: Integrate Redis client in Card Service for (requestId, posServiceHost) mapping (#3524) * Integrate Redis client in Card Service for (requestId, posServiceHost) mapping * remove unused dep * prettier fix * Separate logging params from the message itself * ttl * prettier fix * Rewrite redis service tests to use testcontainers instead of mocks --------- Co-authored-by: Antoniu Neacsu <[email protected]> * feat(point-of-sale): added route for registering a POS device (#3555) * Route for registering a POS device * Fixed issue addressed in comments, tried to fix the port issue of jest * Changed test container port to 0, format fix * feat(wip): merge pos-card-services * feat(point-of-sale): handle incoming payment completed webhooks from backend * fix: typo, expose incoming payment url in gql * fix: typo & unintended changes * chore: regenerate gql * feat: clean up request map if wehbook times out --------- Co-authored-by: oana-lolea <[email protected]> Co-authored-by: zeppelin44 <[email protected]> Co-authored-by: Antoniu Neacsu <[email protected]> * fix: test * feat(card-service): call outgoing payment creation during payment route (#3614) * feat(card-service): call outgoing payment creation during payment route * chore: regenerate graphql * chore: regenerate gql * chore(backend): remove tenant id from card service path in WA response (#3627) * chore(point-of-sale): add expiry for incoming payments created by pos service (#3623) * chore(point-of-sale): add expiry for incoming payments created by pos service * chore(point-of-sale): use jest timers for incoming payment expiry in tests * feat(card-service): remove `debitAmount` from outgoing payment creation admin API request (#3632) * chore(pos, card-service): update generated graphql types * feat(card-service): remove debitAmount from outgoing payment creation mutation * feat(backend): add custom webhook URL for POS (#3628) * feat(backend): add custom webhook URL for POS * fix(backend): remove fallback webhook URL for POS * fix(point-of-sale): added bruno script + added missing env variables to local docker compose file (#3629) * Added bruno script + added missing env variables to local docker containers * Added missing env variables for card-service * Sent tenant id to backend for now, updated bruno req, fixed createIncPayment mutation * Removed unnecessary header * Fixed a test after mutation update * Updated generated graphql files * Fixed connection between payment service calls * Fixed env variables and mutation type for creating inc payment * fix: match payment bodies for pos and card service (#3653) * Matched bodies between pos and card services /payment * Forgot to stage this * Fixed test * Updated graphql types * feat(card-service, pos-service): updating payment routes with new payload (#3655) * chore: update docker compose file to make webhook signatures work * feat(pos): update /payment request payload * feat(card-service): updating payment handler with new payload * chore(bruno): update initiate Payment request * chore: lint OpenAPI * feat(backend): additional webhook events for outgoing payments (#3651) * feat(backend): add additional webhook events for outgoing payments * feat(backend): update webhook recipients logic * chore(backend): extract funded and cancelled events into a new type * chore(backend): move IncomingPaymentInitiationReason to separate file * chore(backend): simplify webhook recipients logic * feat(backend): Update handling of `OutgoingPaymentCardDetails` (#3658) * feat(backend): update CardDetailsInput GraphQL type * feat(backend): update OutgoingPaymentCardDetails model * feat(backend): start publishing cardDetails in outgoing_payment.created webhook * chore(backend): remove old expiry check * test(backend): update outgoing payment resolver test * chore(backend): remove unused cardDetails from GraphQL API * test(backend): update outgoing payment resolver test * chore(backend): update migration to not add already included requestId * chore(backend): update outgoing payment test * feat(card-service): update outgoing payment creation with new payload * test(backend): update outgoing payment test * fix(backend): fix webhook resolver filter for OP funded and cancelled events (#3662) * chore: add sha.js override to fix security vulnerability * feat(card-service): handle payment cancelled & funded events (#3667) * feat(card-service): handle payment cancelled & funded events * feat(card-service): fix tests * fix: updates to make e2e payment flow work (#3668) * chore(localenv): add CARD_WEBHOOK_SERVICE_URL to cloud nine wallet backend * feat(backend): fetch cardDetails during outgoing payment funded and cancelled * chore(pos): correctly handle response from card service * test(pos): update card service client test * chore(card-service): add paymentRoutes to AppServices * chore(backend): fix withGraphFetched query * test(pos): remove unused test * fix(card-service): update payment result type * chore(card-service): format --------- Co-authored-by: Max Kurapov <[email protected]> * chore: add card-service and pos-service image build steps in CI (#3657) * Added card-service and point-of-sale images when pushing to registry * Added dockerfile.prod for card-service * Added spectral to validate card-service open api specs * Fix on building the packages * Fixed dockerfile * Added token-introspection * trying to fix crypto issue * Another try to fix card-service pipeline * Still trying * Testing if crypto is actually the issue here * Trying to debug * Added @types/node so it can see the crypto package * Updated yaml for card-service, removed unnecessary changes * Fix format * Updated axios version of pos * Added tags to card-service.yaml * Removed token-introspection from pos and card services * Added command to run pos and card services in docker file * chore(point-of-sale): update pos service response structure (#3675) * chore(point-of-sale): update pos service response structure * fix: map cleanup in finally block * feat: add integration test for pos-card flow (#3678) * added integration test for pos flow * updated pnpm lock * Added webhook urls and signature secrets to c9 and hlf env * Set up hosts for card service and pos for IT * Added test env to performance test job * Updated IT structure and test name, removed unnecessary formatting * Forgot to remove 'card_expired' from result * Updated result model after merging pos-cards branch * Used prod docker files for pos and card services, added open api files to card-service build, fixed axios dependency issue * feat: added sender wallet address to incoming payment (#3705) * Added sender wallet address to incoming payment * chore(card,pos-service): update alpine image * chore(card-service, pos-service): cleanup unused code (#3718) * chore(point-of-sale): remove merchant service, knex, db connections * chore(card-service): remove knex, objection, db connection * chore(localenv): remove db connections for pos and card service * chore(pos): remove migration folder from dockerfile * chore(bruno): remove unused POS service APIs * chore(testenv): remove db connection for card and pos services * chore(pos, card-service): use core imports from apollo client * chore(point-of-sale, card-service): update webhook handling (#3725) * chore(card-service): rename `/payment-event` route to `/webhook` * chore(point-of-sale): make webhook signature signing optional * chore(testenv): update CARD_WEBHOOK_SERVICE_URL * test(point-of-sale): allow optional webhook signature * feat(point-of-sale): pos service API for getting incoming payments (#3708) * feat(point-of-sale): API for getting pos service's incoming payments * fix: tests * feat: filter out unnecessary fields in response * chore: bruno collection urls * feat: include senderWalletAddress in query * fix: bruno urls * fix: serialize query params properly for gql requests * fix: expose tenant id in payment gql requests * feat: use open payments-esque response format * feat: include metadata * feat: remove unnecessary fields * fix: regenerate gql * fix: imports * fix: proper object assign use and pr comments * feat(backend): add filtering incoming payments by initiatedBy (#3714) * add filtering incoming payments by initiatedBy * Added filter to walletAddress.incomingPayments resolver * added filtering by initiatedBy to also work with notIn * Added filter to getPage functions * feat(point-of-sale): filter incoming payments by those initiated by card payemnt (#3734) * chore(card-service): remove unused components (#3736) * chore(card-service): remove pos-store * chore(backend): remove redis from instantiation * chore: remove unused pos & card service components (#3737) * chore(testenv): remove port * chore(localenv): removed card & pos volumes, ports, seed * chore(card-service): remove init script * chore(backend): remove unused card service * chore(backend): remove card expiry from outgoing payment errors * feat(point-of-sale): add `senderWalletAddress` to incoming payment creation (#3738) * feat(point-of-sale): add USE_HTTP flag * feat(point-of-sale): pass in senderWalletAddress into incoming payment creation * chore(testenv): add USE_HTTP to point-of-sale service * chore(point-of-sale): update card service client log service name * test(point-of-sale): update payment route & service tests --------- Co-authored-by: oana-lolea <[email protected]> Co-authored-by: Nathan Lie <[email protected]> Co-authored-by: Arpi Lengyel <[email protected]> Co-authored-by: Arpi Lengyel <[email protected]> Co-authored-by: xplicit <[email protected]> Co-authored-by: zeppelin44 <[email protected]> Co-authored-by: Antoniu Neacsu <[email protected]> Co-authored-by: MiguelLescasJorgeSebastian <[email protected]> Co-authored-by: HRadry <[email protected]> Co-authored-by: Raul <[email protected]> Co-authored-by: Raul Ranete <[email protected]> Co-authored-by: dragosp1011 <[email protected]> Co-authored-by: Bogdan S <[email protected]>
1 parent 362b9d6 commit 1eb43ae

File tree

8 files changed

+224
-51
lines changed

8 files changed

+224
-51
lines changed

localenv/cloud-nine-wallet/docker-compose.yml

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,42 +30,6 @@ services:
3030
interval: 30s
3131
retries: 1
3232
timeout: 3s
33-
cloud-nine-wallet-point-of-sale:
34-
hostname: cloud-nine-wallet-point-of-sale
35-
image: rafiki-point-of-sale
36-
build:
37-
context: ../..
38-
dockerfile: ./packages/point-of-sale/Dockerfile.dev
39-
restart: always
40-
networks:
41-
- rafiki
42-
ports:
43-
- '3008:3008'
44-
volumes:
45-
- type: bind
46-
source: ../../packages/point-of-sale/src
47-
target: /home/rafiki/packages/point-of-sale/src
48-
read_only: true
49-
environment:
50-
NODE_ENV: ${NODE_ENV:-development}
51-
INSTANCE_NAME: CLOUD-NINE
52-
TRUST_PROXY: ${TRUST_PROXY}
53-
LOG_LEVEL: debug
54-
PORT: 3008
55-
DATABASE_URL: postgresql://cloud_nine_wallet_point_of_sale:cloud_nine_wallet_point_of_sale@shared-database/cloud_nine_wallet_point_of_sale
56-
TENANT_ID: 438fa74a-fa7d-4317-9ced-dde32ece1787
57-
TENANT_SECRET: iyIgCprjb9uL8wFckR+pLEkJWMB7FJhgkvqhTQR/964=
58-
GRAPHQL_URL: http://cloud-nine-wallet-backend:3001/graphql
59-
WEBHOOK_SIGNATURE_SECRET: webhook_secret
60-
depends_on:
61-
- shared-database
62-
healthcheck:
63-
test: ["CMD", "wget", "--spider", "http://localhost:3008/healthz"]
64-
start_period: 60s
65-
start_interval: 5s
66-
interval: 30s
67-
retries: 1
68-
timeout: 3s
6933
cloud-nine-mock-ase:
7034
hostname: cloud-nine-wallet
7135
image: rafiki-mock-ase

packages/card-service/src/config/app.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { ConnectionOptions } from 'tls'
2-
import * as fs from 'fs'
3-
41
function envString(name: string, defaultValue?: string): string {
52
const envValue = process.env[name]
63

packages/point-of-sale/src/app.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ export class App {
9090
webhookHandlerRoutes.handleWebhook
9191
)
9292

93-
// POST /payment
94-
// Initiate a payment
95-
router.post<DefaultState, PaymentContext>('/payment', paymentRoutes.payment)
96-
9793
// POST /refund
9894
// Refund a payment
9995
router.post<DefaultState, RefundContext>(

packages/point-of-sale/src/payments/routes.test.ts

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,209 @@ describe('Payment Routes', () => {
402402
expect(ctx.status).toEqual(400)
403403
expect(ctx.body).toEqual(refundError.message)
404404
})
405+
test(
406+
'falls back to http for payment request if configured',
407+
withConfigOverride(
408+
() => config,
409+
{ useHttp: true },
410+
async () => {
411+
const senderWalletAddress = 'https://example.com/'
412+
413+
const ctx = createPaymentContext({ senderWalletAddress })
414+
415+
const { getWalletAddressSpy } = mockPaymentService()
416+
jest
417+
.spyOn(cardServiceClient, 'sendPayment')
418+
.mockResolvedValueOnce(Result.APPROVED)
419+
420+
jest
421+
.spyOn(webhookWaitMap, 'setWithExpiry')
422+
.mockImplementationOnce((key, deferred) => {
423+
deferred.resolve({
424+
id: v4(),
425+
type: 'incoming_payment.completed',
426+
data: { id: key, completed: true }
427+
})
428+
return webhookWaitMap
429+
})
430+
431+
await paymentRoutes.payment(ctx)
432+
expect(getWalletAddressSpy).toHaveBeenCalledWith(
433+
'http://example.com/'
434+
)
435+
expect(ctx.response.body).toEqual({
436+
result: { code: Result.APPROVED }
437+
})
438+
expect(ctx.status).toBe(200)
439+
}
440+
)
441+
)
442+
})
443+
444+
describe('get incoming payments', (): void => {
445+
test('can get incoming payments for pos device', async (): Promise<void> => {
446+
const walletAddressId = v4()
447+
const mockServiceResponse = {
448+
edges: [
449+
{
450+
node: {
451+
__typename: 'IncomingPayment' as const,
452+
id: v4(),
453+
url: faker.internet.url(),
454+
walletAddressId,
455+
client: faker.internet.url(),
456+
state: IncomingPaymentState.Pending,
457+
incomingAmount: {
458+
__typename: 'Amount' as const,
459+
value: BigInt(500),
460+
assetCode: 'USD',
461+
assetScale: 2
462+
},
463+
receivedAmount: {
464+
__typename: 'Amount' as const,
465+
value: BigInt(500),
466+
assetCode: 'USD',
467+
assetScale: 2
468+
},
469+
expiresAt: new Date().toString(),
470+
createdAt: new Date().toString(),
471+
tenantId: v4(),
472+
initiatedBy: 'CARD'
473+
},
474+
cursor: walletAddressId
475+
}
476+
],
477+
pageInfo: {
478+
endCursor: walletAddressId,
479+
hasNextPage: false,
480+
hasPreviousPage: false,
481+
startCursor: walletAddressId
482+
}
483+
}
484+
const getIncomingPaymentsSpy = jest
485+
.spyOn(paymentService, 'getIncomingPayments')
486+
.mockResolvedValue(mockServiceResponse)
487+
const ctx = createGetPaymentsContext()
488+
489+
await paymentRoutes.getPayments(ctx)
490+
expect(ctx.status).toEqual(200)
491+
expect(ctx.body).toEqual({
492+
// Ensure that typename is sanitized
493+
result: mockServiceResponse.edges.map((edge) => {
494+
const {
495+
__typename: _nodeTypename,
496+
receivedAmount,
497+
incomingAmount,
498+
...restOfNode
499+
} = edge.node
500+
const { __typename: _receivedTypename, ...restOfReceived } =
501+
receivedAmount
502+
const { __typename: _incomingTypename, ...restOfIncoming } =
503+
incomingAmount
504+
return {
505+
...restOfNode,
506+
incomingAmount: restOfIncoming,
507+
receivedAmount: restOfReceived
508+
}
509+
}),
510+
pagination: mockServiceResponse.pageInfo
511+
})
512+
513+
expect(getIncomingPaymentsSpy).toHaveBeenCalledWith({
514+
receiverWalletAddress: ctx.query.receiverWalletAddress,
515+
filter: {
516+
initiatedBy: {
517+
in: ['CARD']
518+
}
519+
}
520+
})
521+
})
522+
523+
test('returns empty page if no incoming payments', async (): Promise<void> => {
524+
jest
525+
.spyOn(paymentService, 'getIncomingPayments')
526+
.mockResolvedValue(undefined)
527+
528+
const ctx = createGetPaymentsContext()
529+
530+
await paymentRoutes.getPayments(ctx)
531+
expect(ctx.status).toEqual(200)
532+
expect(ctx.body).toMatchObject({
533+
result: [],
534+
pagination: {
535+
hasNextPage: false,
536+
hasPreviousPage: false
537+
}
538+
})
539+
})
540+
541+
test('passes through pagination filters', async (): Promise<void> => {
542+
const beforeWalletAddressId = v4()
543+
const afterWalletAddressId = v4()
544+
const walletAddressId = v4()
545+
const mockServiceResponse = {
546+
edges: [
547+
{
548+
node: {
549+
__typename: 'IncomingPayment' as const,
550+
id: v4(),
551+
url: faker.internet.url(),
552+
walletAddressId,
553+
client: faker.internet.url(),
554+
state: IncomingPaymentState.Pending,
555+
incomingAmount: {
556+
__typename: 'Amount' as const,
557+
value: BigInt(500),
558+
assetCode: 'USD',
559+
assetScale: 2
560+
},
561+
receivedAmount: {
562+
__typename: 'Amount' as const,
563+
value: BigInt(500),
564+
assetCode: 'USD',
565+
assetScale: 2
566+
},
567+
expiresAt: new Date().toString(),
568+
createdAt: new Date().toString(),
569+
tenantId: v4(),
570+
initiatedBy: 'CARD'
571+
},
572+
cursor: walletAddressId
573+
}
574+
],
575+
pageInfo: {
576+
endCursor: afterWalletAddressId,
577+
hasNextPage: false,
578+
hasPreviousPage: false,
579+
startCursor: beforeWalletAddressId
580+
}
581+
}
582+
const getIncomingPaymentsSpy = jest
583+
.spyOn(paymentService, 'getIncomingPayments')
584+
.mockResolvedValue(mockServiceResponse)
585+
const ctx = createGetPaymentsContext({
586+
sortOrder: SortOrder.Asc,
587+
first: 1,
588+
last: 1,
589+
before: beforeWalletAddressId,
590+
after: afterWalletAddressId
591+
})
592+
593+
await paymentRoutes.getPayments(ctx)
594+
expect(getIncomingPaymentsSpy).toHaveBeenCalledWith({
595+
receiverWalletAddress: ctx.query.receiverWalletAddress,
596+
sortOrder: SortOrder.Asc,
597+
first: 1,
598+
last: 1,
599+
before: beforeWalletAddressId,
600+
after: afterWalletAddressId,
601+
filter: {
602+
initiatedBy: {
603+
in: ['CARD']
604+
}
605+
}
606+
})
607+
})
405608
})
406609
})
407610

packages/point-of-sale/src/payments/routes.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,20 @@ export type RefundContext = Exclude<AppContext, ['request']> & {
8181
request: RefundRequest
8282
}
8383

84+
export interface GetPaymentsQuery {
85+
receiverWalletAddress: string
86+
sortOrder?: SortOrder
87+
first?: number
88+
last?: number
89+
before?: string
90+
after?: string
91+
filter?: IncomingPaymentFilter
92+
}
93+
8494
export interface PaymentRoutes {
8595
getPayments(ctx: GetPaymentsContext): Promise<void>
8696
payment(ctx: PaymentContext): Promise<void>
97+
getPayments(ctx: GetPaymentsContext): Promise<void>
8798
refundPayment(ctx: RefundContext): Promise<void>
8899
}
89100

packages/point-of-sale/src/payments/service.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { PaymentService, createPaymentService } from './service'
22
import { ApolloClient, NormalizedCacheObject } from '@apollo/client'
33
import { Logger } from 'pino'
4+
import { CREATE_RECEIVER } from '../graphql/mutations/createReceiver'
5+
import { CREATE_OUTGOING_PAYMENT_FROM_INCOMING_PAYMENT } from '../graphql/mutations/createOutgoingPaymentFromIncomingPayment'
46
import { AmountInput, IncomingPaymentState } from '../graphql/generated/graphql'
57
import { IAppConfig } from '../config/app'
68
import { v4 as uuid, v4 } from 'uuid'
79
import { AxiosInstance } from 'axios'
810
import { faker } from '@faker-js/faker'
911
import { GET_WALLET_ADDRESS_BY_URL } from '../graphql/queries/getWalletAddress'
1012
import { GET_INCOMING_PAYMENT } from '../graphql/queries/getIncomingPayment'
11-
import { CREATE_RECEIVER } from '../graphql/mutations/createReceiver'
12-
import { CREATE_OUTGOING_PAYMENT_FROM_INCOMING_PAYMENT } from '../graphql/mutations/createOutgoingPaymentFromIncomingPayment'
1313

1414
const mockLogger = {
1515
child: jest.fn().mockReturnThis(),
@@ -273,9 +273,9 @@ describe('get payments', (): void => {
273273
})
274274
})
275275
})
276+
276277
describe('refundIncomingPayment', () => {
277278
let service: PaymentService
278-
// const WALLET_ADDRESS_URL = 'https://api.example.com/wallet-address'
279279

280280
beforeAll(() => {
281281
service = createPaymentService(deps)

packages/point-of-sale/src/payments/service.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { Logger } from 'pino'
22
import { CREATE_INCOMING_PAYMENT } from '../graphql/mutations/createIncomingPayment'
33
import { IAppConfig } from '../config/app'
4-
import { ApolloClient, NormalizedCacheObject, gql } from '@apollo/client'
4+
import { ApolloClient, NormalizedCacheObject } from '@apollo/client'
5+
import { AxiosInstance, AxiosRequestConfig } from 'axios'
6+
import { v4 } from 'uuid'
57
import {
68
AmountInput,
79
CreateIncomingPayment,
@@ -18,8 +20,6 @@ import {
1820
GetWalletAddress,
1921
GetWalletAddressVariables
2022
} from '../graphql/generated/graphql'
21-
import { v4 } from 'uuid'
22-
import { AxiosInstance, AxiosRequestConfig } from 'axios'
2323
import { GET_WALLET_ADDRESS_BY_URL } from '../graphql/queries/getWalletAddress'
2424
import { GetPaymentsQuery } from './routes'
2525
import { GET_INCOMING_PAYMENT } from '../graphql/queries/getIncomingPayment'
@@ -91,14 +91,14 @@ export function createPaymentService(
9191
}
9292

9393
return {
94-
getIncomingPayments: (options: GetPaymentsQuery) =>
95-
getIncomingPayments(deps, options),
9694
createIncomingPayment: (args: CreateIncomingPaymentArgs) =>
9795
createIncomingPayment(deps, args),
9896
getWalletAddress: (walletAddressUrl: string) =>
9997
getWalletAddress(deps, walletAddressUrl),
10098
getWalletAddressIdByUrl: (walletAddressUrl: string) =>
10199
getWalletAddressIdByUrl(deps, walletAddressUrl),
100+
getIncomingPayments: (options: GetPaymentsQuery) =>
101+
getIncomingPayments(deps, options),
102102
refundIncomingPayment: (
103103
incomingPaymentId: string,
104104
posWalletAddress: string

test/testenv/cloud-nine-wallet/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ services:
9494
restart: always
9595
networks:
9696
- rafiki-test
97+
ports:
98+
- '3104:3104'
9799
environment:
98100
NODE_ENV: ${NODE_ENV:-development}
99101
INSTANCE_NAME: CLOUD-NINE

0 commit comments

Comments
 (0)