Here is the function I use in an Angular5/Typescript environment using RecurlyJS. It's important to recognize the difference between a billing token for credit card vs bank account.
private getRecurlyToken(locationId): Promise<string> {
return new Promise<string>((resolve, reject) => {
let recurly = window['recurly'];
recurly.configure({publicKey: Config['RECURLY_PUBLIC_KEY'], parent: false});
if(this.paymentMethod.value === 'card') {
recurly.token({
number: this.cardInfoForm.value.cardNumber,
month: this.cardInfoForm.value.expMonth,
year: this.cardInfoForm.value.expYear,
first_name: this.cardInfoForm.value.firstName,
last_name: this.cardInfoForm.value.lastName,
cvv: this.cardInfoForm.value.cardCVC,
address1: this.billingAddressForm.value.address1,
address2: this.billingAddressForm.value.address2,
city: this.billingAddressForm.value.city,
state: this.billingAddressForm.value.state,
postal_code: this.billingAddressForm.value.postalCode,
country: 'US',
}, (error, token) => {
if(error && error.code === 'validation') { return reject(this.validationError('credit card', error)); }
else if(error) { return reject(error); }
resolve(token.id);
});
} else {
recurly.bankAccount.token({
name_on_account: this.bankInfoForm.value.nameOnAccount,
account_number: this.bankInfoForm.value.accountNumber,
account_number_confirmation: this.bankInfoForm.value.accountConfirmation,
routing_number: this.bankInfoForm.value.routingNumber,
account_type: this.bankInfoForm.value.accountType,
address1: this.billingAddressForm.value.address1,
address2: this.billingAddressForm.value.address2,
city: this.billingAddressForm.value.city,
state: this.billingAddressForm.value.state,
postal_code: this.billingAddressForm.value.postalCode,
country: 'US',
}, (error, token) => {
if(error && error.code === 'validation') { return reject(this.validationError('bank', error)); }
else if(error) { return reject(error); }
resolve(token.id);
});
}
});
}