Skip to content

Commit

Permalink
feat: add cards tokenisation endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
andrejak committed Nov 15, 2023
1 parent 63c00a8 commit 9098621
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Vault/Cards/Cards.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import nock from 'nock'
import { Duffel } from '../../index'

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

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 } })

const response = await duffel.cards.create({
address_city: 'London',
address_country_code: 'GB',
address_line_1: '1 Downing St',
address_postal_code: 'EC2A 4RQ',
address_region: 'London',
brand: 'visa',
expiry_month: '03',
expiry_year: '30',
name: 'Neil Armstrong',
number: '4242424242424242',
cvc: '123',
})
expect(response.data.id).toBe(MOCK_ID)
})
})
85 changes: 85 additions & 0 deletions src/Vault/Cards/Cards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Client } from '../../Client'
import { Resource } from '../../Resource'
import { DuffelResponse } from '../../types'

export type CardBrand =
| 'visa'
| 'mastercard'
| 'uatp'
| 'american_express'
| 'diners_club'
| 'jcb'

interface CardParameters {
/**
* The first line of the card owner's address
*/
address_line_1: string

/**
* The card owner's postal code (or zip code)
*/
address_postal_code: string
/**
* The card owner's city
*/
address_city: string
/**
* The card owner's region or state
*/
address_region: string
/**
* The ISO 3166-1 alpha-2 code for the card owner's country
*/
address_country_code: string
/**
* The brand or the type of the card
*/
brand: CardBrand
/**
* The month that the card expires in as a two-digit string, e.g. "01"
*/
expiry_month: string
/**
* The year that the card expires in as a two-digit string, e.g. "28"
*/
expiry_year: string
/**
* The card owner's name
*/
name: string
/**
* The card number
*/
number: string
/**
* The card verification code
*/
cvc: string
}

interface CardRecord {
id: string
live_mode: boolean
}

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

// basePath must be 'https://api.duffel.cards'
constructor(client: Client) {
super(client)
this.path = 'vault/cards'
}

/**
* Create a Duffel card record
*/
public create = async (
data: CardParameters,
): Promise<DuffelResponse<CardRecord>> =>
this.request({ method: 'POST', path: this.path, data })
}
1 change: 1 addition & 0 deletions src/Vault/Cards/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Cards'
1 change: 1 addition & 0 deletions src/Vault/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Cards'
11 changes: 11 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +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'

export interface DuffelAPIClient {
aircraft: Aircraft
airlines: Airlines
Expand Down Expand Up @@ -57,6 +59,9 @@ export class Duffel {
public webhooks: Webhooks
public stays: Stays

private cardsClient: Client
public cards: Cards

constructor(config: Config) {
this.client = new Client(config)

Expand All @@ -80,6 +85,12 @@ export class Duffel {
this.refunds = new Refunds(this.client)
this.webhooks = new Webhooks(this.client)
this.stays = new Stays(this.client)

this.cardsClient = new Client({
...config,
basePath: 'https://api.duffel.cards',
})
this.cards = new Cards(this.cardsClient)
}
}

Expand Down

0 comments on commit 9098621

Please sign in to comment.