Skip to content

Commit d9eac6a

Browse files
authored
Merge pull request #983 from duffelhq/PAY-1655
feat: add 3DS session support and update to cards endpoint
2 parents d241e4b + 9ff22e7 commit d9eac6a

File tree

9 files changed

+128
-5
lines changed

9 files changed

+128
-5
lines changed

src/Vault/Cards/Cards.spec.ts renamed to src/Payments/Cards/Cards.spec.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@ describe('Cards', () => {
1010
it('should create a card record when `create` is called', async () => {
1111
const MOCK_ID = 'tcd_00009hthhsUZ8W4LxQgkjb'
1212
nock(/(.*)/)
13-
.post('/vault/cards')
14-
.reply(200, { data: { id: MOCK_ID, liveMode: false } })
13+
.post('/payments/cards')
14+
.reply(200, {
15+
data: {
16+
id: MOCK_ID,
17+
liveMode: false,
18+
unavailableAt: '2024-01-01T00:00:00',
19+
brand: 'visa',
20+
multiUse: false,
21+
last4Digits: '4242',
22+
},
23+
})
1524

1625
const response = await duffel.cards.create({
1726
address_city: 'London',
@@ -25,6 +34,7 @@ describe('Cards', () => {
2534
name: 'Neil Armstrong',
2635
number: '4242424242424242',
2736
cvc: '123',
37+
multi_use: false,
2838
})
2939
expect(response.data.id).toBe(MOCK_ID)
3040
})

src/Vault/Cards/Cards.ts renamed to src/Payments/Cards/Cards.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,19 @@ interface CardParameters {
5656
* The card verification code
5757
*/
5858
cvc: string
59+
/**
60+
* Set to true to indicate that this card can be used multiple times
61+
*/
62+
multi_use: boolean
5963
}
6064

6165
interface CardRecord {
6266
id: string
6367
live_mode: boolean
68+
multi_use: boolean
69+
unavailble_at: string
70+
brand: string
71+
last_4_digits: string
6472
}
6573

6674
export class Cards extends Resource {
@@ -72,7 +80,7 @@ export class Cards extends Resource {
7280
// basePath must be 'https://api.duffel.cards'
7381
constructor(client: Client) {
7482
super(client)
75-
this.path = 'vault/cards'
83+
this.path = 'payments/cards'
7684
}
7785

7886
/**
File renamed without changes.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import nock from 'nock'
2+
import { Duffel } from '../../index'
3+
4+
const duffel = new Duffel({ token: 'mockToken' })
5+
describe('ThreeDSecureSessions', () => {
6+
afterEach(() => {
7+
nock.cleanAll()
8+
})
9+
10+
it('should create a 3DS session record when `create` is called', async () => {
11+
const MOCK_ID = '3ds_00009hthhsUZ8W4LxQgkjb'
12+
nock(/(.*)/)
13+
.post('/payments/three_d_secure_sessions')
14+
.reply(200, {
15+
data: {
16+
id: MOCK_ID,
17+
liveMode: false,
18+
expiresAt: '2024-01-01T00:00:00',
19+
status: 'ready_for_payment',
20+
resourceId: 'off_00009hthhsUZ8W4LxQgkjb',
21+
clientId: 'tds_57aa862f8bf7',
22+
cardId: 'tcd_00009hthhsUZ8W4LxQgkjb',
23+
},
24+
})
25+
26+
const response = await duffel.three_d_secure_sessions.create({
27+
resource_id: 'off_00009hthhsUZ8W4LxQgkjb',
28+
card_id: 'tcd_00009hthhsUZ8W4LxQgkjb',
29+
services: [{ quantity: 1, id: 'ser_00009UhD4ongolulWd9123' }],
30+
exception: 'secure_corporate_payment',
31+
})
32+
expect(response.data.id).toBe(MOCK_ID)
33+
})
34+
})
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Resource } from '../../Resource'
2+
import { DuffelResponse } from '../../types'
3+
4+
interface Service {
5+
/**
6+
* The quantity of the service ID to pay for
7+
*/
8+
quantity: number
9+
/**
10+
* The ID of the service to pay for
11+
*/
12+
id: string
13+
}
14+
15+
interface ThreeDSecureSessionParameters {
16+
/**
17+
* The offer ID, order ID, order change ID or quote ID intended to pay
18+
*/
19+
resource_id: string
20+
21+
/**
22+
* The services inteded to pay
23+
*/
24+
services: Service[]
25+
26+
/**
27+
* The card ID
28+
*/
29+
card_id: string
30+
31+
/**
32+
* The exception name for the 3DS session
33+
*/
34+
exception: string
35+
}
36+
37+
interface ThreeDSecureSessionRecord {
38+
id: string
39+
resource_id: string
40+
card_id: string
41+
live_mode: boolean
42+
expires_at: string
43+
status: string
44+
client_id: string
45+
}
46+
47+
export class ThreeDSecureSessions extends Resource {
48+
/**
49+
* Endpoint path
50+
*/
51+
path: string
52+
53+
constructor(args: any) {
54+
super(args)
55+
this.path = 'payments/three_d_secure_sessions'
56+
}
57+
58+
/**
59+
* Create a Duffel ThreeDSecureSession record
60+
*/
61+
public create = async (
62+
data: ThreeDSecureSessionParameters,
63+
): Promise<DuffelResponse<ThreeDSecureSessionRecord>> =>
64+
this.request({ method: 'POST', path: this.path, data })
65+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './ThreeDSecureSessions'

src/Payments/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './Cards'
2+
export * from './ThreeDSecureSessions'

src/Vault/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import { Refunds } from './DuffelPayments/Refunds'
1919
import { Sessions } from './Links'
2020
import { Webhooks } from './notifications'
2121
import { Stays } from './Stays/Stays'
22-
import { Cards } from './Vault/Cards'
22+
import { Cards } from './Payments/Cards'
23+
import { ThreeDSecureSessions } from './Payments/ThreeDSecureSessions'
2324

2425
export interface DuffelAPIClient {
2526
aircraft: Aircraft
@@ -34,6 +35,7 @@ export interface DuffelAPIClient {
3435
orderCancellations: OrderCancellations
3536
payments: Payments
3637
seatMaps: SeatMaps
38+
threeDSecureSessions: ThreeDSecureSessions
3739
}
3840

3941
export class Duffel {
@@ -58,6 +60,7 @@ export class Duffel {
5860
public refunds: Refunds
5961
public webhooks: Webhooks
6062
public stays: Stays
63+
public three_d_secure_sessions: ThreeDSecureSessions
6164

6265
private cardsClient: Client
6366
public cards: Cards
@@ -85,6 +88,7 @@ export class Duffel {
8588
this.refunds = new Refunds(this.client)
8689
this.webhooks = new Webhooks(this.client)
8790
this.stays = new Stays(this.client)
91+
this.three_d_secure_sessions = new ThreeDSecureSessions(this.client)
8892

8993
this.cardsClient = new Client({
9094
...config,

0 commit comments

Comments
 (0)