Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add 3DS session support and update to cards endpoint #983

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,17 @@ describe('Cards', () => {
it('should create a card record when `create` is called', async () => {
const MOCK_ID = 'tcd_00009hthhsUZ8W4LxQgkjb'
nock(/(.*)/)
.post('/vault/cards')
.reply(200, { data: { id: MOCK_ID, liveMode: false } })
.post('/payments/cards')
.reply(200, {
data: {
id: MOCK_ID,
liveMode: false,
unavailableAt: '2024-01-01T00:00:00',
brand: 'visa',
multiUse: false,
last4Digits: '4242',
},
})

const response = await duffel.cards.create({
address_city: 'London',
Expand All @@ -25,6 +34,7 @@ describe('Cards', () => {
name: 'Neil Armstrong',
number: '4242424242424242',
cvc: '123',
multi_use: false,
})
expect(response.data.id).toBe(MOCK_ID)
})
Expand Down
10 changes: 9 additions & 1 deletion src/Vault/Cards/Cards.ts → src/Payments/Cards/Cards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,19 @@ interface CardParameters {
* The card verification code
*/
cvc: string
/**
* Set to true to indicate that this card can be used multiple times
*/
multi_use: boolean
}

interface CardRecord {
id: string
live_mode: boolean
multi_use: boolean
unavailble_at: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brand: string
last_4_digits: string
}

export class Cards extends Resource {
Expand All @@ -72,7 +80,7 @@ export class Cards extends Resource {
// basePath must be 'https://api.duffel.cards'
constructor(client: Client) {
super(client)
this.path = 'vault/cards'
this.path = 'payments/cards'
}

/**
Expand Down
File renamed without changes.
34 changes: 34 additions & 0 deletions src/Payments/ThreeDSecureSessions/ThreeDSecureSessions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import nock from 'nock'
import { Duffel } from '../../index'

const duffel = new Duffel({ token: 'mockToken' })
describe('ThreeDSecureSessions', () => {
afterEach(() => {
nock.cleanAll()
})

it('should create a 3DS session record when `create` is called', async () => {
const MOCK_ID = '3ds_00009hthhsUZ8W4LxQgkjb'
nock(/(.*)/)
.post('/payments/three_d_secure_sessions')
.reply(200, {
data: {
id: MOCK_ID,
liveMode: false,
expiresAt: '2024-01-01T00:00:00',
status: 'ready_for_payment',
resourceId: 'off_00009hthhsUZ8W4LxQgkjb',
clientId: 'tds_57aa862f8bf7',
cardId: 'tcd_00009hthhsUZ8W4LxQgkjb',
},
})

const response = await duffel.three_d_secure_sessions.create({
resource_id: 'off_00009hthhsUZ8W4LxQgkjb',
card_id: 'tcd_00009hthhsUZ8W4LxQgkjb',
services: [{ quantity: 1, id: 'ser_00009UhD4ongolulWd9123' }],
exception: 'secure_corporate_payment',
})
expect(response.data.id).toBe(MOCK_ID)
})
})
65 changes: 65 additions & 0 deletions src/Payments/ThreeDSecureSessions/ThreeDSecureSessions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Resource } from '../../Resource'
import { DuffelResponse } from '../../types'

interface Service {
/**
* The quantity of the service ID to pay for
*/
quantity: number
/**
* The ID of the service to pay for
*/
id: string
}

interface ThreeDSecureSessionParameters {
/**
* The offer ID, order ID, order change ID or quote ID intended to pay
*/
resource_id: string

/**
* The services inteded to pay
*/
services: Service[]

/**
* The card ID
*/
card_id: string

/**
* The exception name for the 3DS session
*/
exception: string
}

interface ThreeDSecureSessionRecord {
id: string
resource_id: string
card_id: string
live_mode: boolean
expires_at: string
status: string
client_id: string
}

export class ThreeDSecureSessions extends Resource {
/**
* Endpoint path
*/
path: string

constructor(args: any) {
super(args)
this.path = 'payments/three_d_secure_sessions'
}

/**
* Create a Duffel ThreeDSecureSession record
*/
public create = async (
data: ThreeDSecureSessionParameters,
): Promise<DuffelResponse<ThreeDSecureSessionRecord>> =>
this.request({ method: 'POST', path: this.path, data })
}
1 change: 1 addition & 0 deletions src/Payments/ThreeDSecureSessions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ThreeDSecureSessions'
2 changes: 2 additions & 0 deletions src/Payments/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './Cards'
export * from './ThreeDSecureSessions'
1 change: 0 additions & 1 deletion src/Vault/index.ts

This file was deleted.

6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import { Refunds } from './DuffelPayments/Refunds'
import { Sessions } from './Links'
import { Webhooks } from './notifications'
import { Stays } from './Stays/Stays'
import { Cards } from './Vault/Cards'
import { Cards } from './Payments/Cards'
import { ThreeDSecureSessions } from './Payments/ThreeDSecureSessions'

export interface DuffelAPIClient {
aircraft: Aircraft
Expand All @@ -34,6 +35,7 @@ export interface DuffelAPIClient {
orderCancellations: OrderCancellations
payments: Payments
seatMaps: SeatMaps
threeDSecureSessions: ThreeDSecureSessions
}

export class Duffel {
Expand All @@ -58,6 +60,7 @@ export class Duffel {
public refunds: Refunds
public webhooks: Webhooks
public stays: Stays
public three_d_secure_sessions: ThreeDSecureSessions

private cardsClient: Client
public cards: Cards
Expand Down Expand Up @@ -85,6 +88,7 @@ export class Duffel {
this.refunds = new Refunds(this.client)
this.webhooks = new Webhooks(this.client)
this.stays = new Stays(this.client)
this.three_d_secure_sessions = new ThreeDSecureSessions(this.client)

this.cardsClient = new Client({
...config,
Expand Down