Skip to content

Commit d719fd8

Browse files
authored
Merge pull request #840 from duffelhq/cards
Add cards tokenisation endpoint
2 parents c1d9dd4 + 9098621 commit d719fd8

File tree

7 files changed

+132
-3
lines changed

7 files changed

+132
-3
lines changed

src/Stays/Bookings/Bookings.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ export class Bookings extends Resource {
6565
* @param {string} bookingId - The ID of the booking
6666
*/
6767
public cancel = async (
68-
bookindId: string,
68+
bookingId: string,
6969
): Promise<DuffelResponse<StaysBooking>> =>
7070
this.request({
7171
method: 'POST',
72-
path: `${this.path}/${bookindId}/actions/cancel`,
72+
path: `${this.path}/${bookingId}/actions/cancel`,
7373
})
7474
}

src/Stays/StaysTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ export interface StaysAddress {
252252
postal_code: string
253253

254254
/**
255-
* The setay's region or state
255+
* The stay's region or state
256256
*/
257257
region: string
258258
}

src/Vault/Cards/Cards.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import nock from 'nock'
2+
import { Duffel } from '../../index'
3+
4+
const duffel = new Duffel({ token: 'mockToken' })
5+
describe('Cards', () => {
6+
afterEach(() => {
7+
nock.cleanAll()
8+
})
9+
10+
it('should create a card record when `create` is called', async () => {
11+
const MOCK_ID = 'tcd_00009hthhsUZ8W4LxQgkjb'
12+
nock(/(.*)/)
13+
.post('/vault/cards')
14+
.reply(200, { data: { id: MOCK_ID, liveMode: false } })
15+
16+
const response = await duffel.cards.create({
17+
address_city: 'London',
18+
address_country_code: 'GB',
19+
address_line_1: '1 Downing St',
20+
address_postal_code: 'EC2A 4RQ',
21+
address_region: 'London',
22+
brand: 'visa',
23+
expiry_month: '03',
24+
expiry_year: '30',
25+
name: 'Neil Armstrong',
26+
number: '4242424242424242',
27+
cvc: '123',
28+
})
29+
expect(response.data.id).toBe(MOCK_ID)
30+
})
31+
})

src/Vault/Cards/Cards.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Client } from '../../Client'
2+
import { Resource } from '../../Resource'
3+
import { DuffelResponse } from '../../types'
4+
5+
export type CardBrand =
6+
| 'visa'
7+
| 'mastercard'
8+
| 'uatp'
9+
| 'american_express'
10+
| 'diners_club'
11+
| 'jcb'
12+
13+
interface CardParameters {
14+
/**
15+
* The first line of the card owner's address
16+
*/
17+
address_line_1: string
18+
19+
/**
20+
* The card owner's postal code (or zip code)
21+
*/
22+
address_postal_code: string
23+
/**
24+
* The card owner's city
25+
*/
26+
address_city: string
27+
/**
28+
* The card owner's region or state
29+
*/
30+
address_region: string
31+
/**
32+
* The ISO 3166-1 alpha-2 code for the card owner's country
33+
*/
34+
address_country_code: string
35+
/**
36+
* The brand or the type of the card
37+
*/
38+
brand: CardBrand
39+
/**
40+
* The month that the card expires in as a two-digit string, e.g. "01"
41+
*/
42+
expiry_month: string
43+
/**
44+
* The year that the card expires in as a two-digit string, e.g. "28"
45+
*/
46+
expiry_year: string
47+
/**
48+
* The card owner's name
49+
*/
50+
name: string
51+
/**
52+
* The card number
53+
*/
54+
number: string
55+
/**
56+
* The card verification code
57+
*/
58+
cvc: string
59+
}
60+
61+
interface CardRecord {
62+
id: string
63+
live_mode: boolean
64+
}
65+
66+
export class Cards extends Resource {
67+
/**
68+
* Endpoint path
69+
*/
70+
path: string
71+
72+
// basePath must be 'https://api.duffel.cards'
73+
constructor(client: Client) {
74+
super(client)
75+
this.path = 'vault/cards'
76+
}
77+
78+
/**
79+
* Create a Duffel card record
80+
*/
81+
public create = async (
82+
data: CardParameters,
83+
): Promise<DuffelResponse<CardRecord>> =>
84+
this.request({ method: 'POST', path: this.path, data })
85+
}

src/Vault/Cards/index.ts

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

src/Vault/index.ts

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

src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +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'
23+
2224
export interface DuffelAPIClient {
2325
aircraft: Aircraft
2426
airlines: Airlines
@@ -57,6 +59,9 @@ export class Duffel {
5759
public webhooks: Webhooks
5860
public stays: Stays
5961

62+
private cardsClient: Client
63+
public cards: Cards
64+
6065
constructor(config: Config) {
6166
this.client = new Client(config)
6267

@@ -80,6 +85,12 @@ export class Duffel {
8085
this.refunds = new Refunds(this.client)
8186
this.webhooks = new Webhooks(this.client)
8287
this.stays = new Stays(this.client)
88+
89+
this.cardsClient = new Client({
90+
...config,
91+
basePath: 'https://api.duffel.cards',
92+
})
93+
this.cards = new Cards(this.cardsClient)
8394
}
8495
}
8596

0 commit comments

Comments
 (0)