update
This commit is contained in:
419
ts/bunq.classes.request.ts
Normal file
419
ts/bunq.classes.request.ts
Normal file
@@ -0,0 +1,419 @@
|
||||
import * as plugins from './bunq.plugins';
|
||||
import { BunqAccount } from './bunq.classes.account';
|
||||
import { BunqMonetaryAccount } from './bunq.classes.monetaryaccount';
|
||||
import {
|
||||
IBunqRequestInquiry,
|
||||
IBunqAmount,
|
||||
IBunqAlias,
|
||||
IBunqPaginationOptions
|
||||
} from './bunq.interfaces';
|
||||
|
||||
export class BunqRequestInquiry {
|
||||
private bunqAccount: BunqAccount;
|
||||
private monetaryAccount: BunqMonetaryAccount;
|
||||
|
||||
// Request properties
|
||||
public id?: number;
|
||||
public created?: string;
|
||||
public updated?: string;
|
||||
public timeResponded?: string;
|
||||
public timeExpiry?: string;
|
||||
public monetaryAccountId?: number;
|
||||
public amountInquired?: IBunqAmount;
|
||||
public amountResponded?: IBunqAmount;
|
||||
public userAliasCreated?: IBunqAlias;
|
||||
public userAliasRevoked?: IBunqAlias;
|
||||
public counterpartyAlias?: IBunqAlias;
|
||||
public description?: string;
|
||||
public merchantReference?: string;
|
||||
public status?: string;
|
||||
public minimumAge?: number;
|
||||
public requireAddress?: string;
|
||||
public bunqmeShareUrl?: string;
|
||||
public redirectUrl?: string;
|
||||
|
||||
constructor(bunqAccount: BunqAccount, monetaryAccount: BunqMonetaryAccount) {
|
||||
this.bunqAccount = bunqAccount;
|
||||
this.monetaryAccount = monetaryAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new request inquiry
|
||||
*/
|
||||
public async create(options: {
|
||||
amountInquired: IBunqAmount;
|
||||
counterpartyAlias: IBunqAlias;
|
||||
description: string;
|
||||
allowBunqme?: boolean;
|
||||
merchantReference?: string;
|
||||
status?: 'PENDING' | 'REVOKED';
|
||||
minimumAge?: number;
|
||||
requireAddress?: 'BILLING' | 'SHIPPING' | 'BILLING_SHIPPING';
|
||||
wantTip?: boolean;
|
||||
allowAmountLower?: boolean;
|
||||
allowAmountHigher?: boolean;
|
||||
redirectUrl?: string;
|
||||
eventId?: number;
|
||||
}): Promise<number> {
|
||||
await this.bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
const requestData = {
|
||||
amount_inquired: options.amountInquired,
|
||||
counterparty_alias: options.counterpartyAlias,
|
||||
description: options.description,
|
||||
allow_bunqme: options.allowBunqme,
|
||||
merchant_reference: options.merchantReference,
|
||||
status: options.status,
|
||||
minimum_age: options.minimumAge,
|
||||
require_address: options.requireAddress,
|
||||
want_tip: options.wantTip,
|
||||
allow_amount_lower: options.allowAmountLower,
|
||||
allow_amount_higher: options.allowAmountHigher,
|
||||
redirect_url: options.redirectUrl,
|
||||
event_id: options.eventId
|
||||
};
|
||||
|
||||
const response = await this.bunqAccount.getHttpClient().post(
|
||||
`/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/request-inquiry`,
|
||||
requestData
|
||||
);
|
||||
|
||||
if (response.Response && response.Response[0] && response.Response[0].Id) {
|
||||
this.id = response.Response[0].Id.id;
|
||||
return this.id;
|
||||
}
|
||||
|
||||
throw new Error('Failed to create request inquiry');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request inquiry details
|
||||
*/
|
||||
public async get(): Promise<IBunqRequestInquiry> {
|
||||
if (!this.id) {
|
||||
throw new Error('Request inquiry ID not set');
|
||||
}
|
||||
|
||||
await this.bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
const response = await this.bunqAccount.getHttpClient().get(
|
||||
`/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/request-inquiry/${this.id}`
|
||||
);
|
||||
|
||||
if (response.Response && response.Response[0] && response.Response[0].RequestInquiry) {
|
||||
const data = response.Response[0].RequestInquiry;
|
||||
this.updateFromApiResponse(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
throw new Error('Request inquiry not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update request inquiry
|
||||
*/
|
||||
public async update(updates: {
|
||||
status?: 'REVOKED';
|
||||
amountInquired?: IBunqAmount;
|
||||
description?: string;
|
||||
}): Promise<void> {
|
||||
if (!this.id) {
|
||||
throw new Error('Request inquiry ID not set');
|
||||
}
|
||||
|
||||
await this.bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
await this.bunqAccount.getHttpClient().put(
|
||||
`/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/request-inquiry/${this.id}`,
|
||||
updates
|
||||
);
|
||||
|
||||
// Refresh data
|
||||
await this.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke the request inquiry
|
||||
*/
|
||||
public async revoke(): Promise<void> {
|
||||
await this.update({ status: 'REVOKED' });
|
||||
}
|
||||
|
||||
/**
|
||||
* List request inquiries for a monetary account
|
||||
*/
|
||||
public static async list(
|
||||
bunqAccount: BunqAccount,
|
||||
monetaryAccountId: number,
|
||||
options?: IBunqPaginationOptions
|
||||
): Promise<IBunqRequestInquiry[]> {
|
||||
await bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
const response = await bunqAccount.getHttpClient().list(
|
||||
`/v1/user/${bunqAccount.userId}/monetary-account/${monetaryAccountId}/request-inquiry`,
|
||||
options
|
||||
);
|
||||
|
||||
const requests: IBunqRequestInquiry[] = [];
|
||||
|
||||
if (response.Response) {
|
||||
for (const item of response.Response) {
|
||||
if (item.RequestInquiry) {
|
||||
requests.push(item.RequestInquiry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update properties from API response
|
||||
*/
|
||||
private updateFromApiResponse(data: any): void {
|
||||
this.id = data.id;
|
||||
this.created = data.created;
|
||||
this.updated = data.updated;
|
||||
this.timeResponded = data.time_responded;
|
||||
this.timeExpiry = data.time_expiry;
|
||||
this.monetaryAccountId = data.monetary_account_id;
|
||||
this.amountInquired = data.amount_inquired;
|
||||
this.amountResponded = data.amount_responded;
|
||||
this.userAliasCreated = data.user_alias_created;
|
||||
this.userAliasRevoked = data.user_alias_revoked;
|
||||
this.counterpartyAlias = data.counterparty_alias;
|
||||
this.description = data.description;
|
||||
this.merchantReference = data.merchant_reference;
|
||||
this.status = data.status;
|
||||
this.minimumAge = data.minimum_age;
|
||||
this.requireAddress = data.require_address;
|
||||
this.bunqmeShareUrl = data.bunqme_share_url;
|
||||
this.redirectUrl = data.redirect_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder for request inquiries
|
||||
*/
|
||||
public static builder(
|
||||
bunqAccount: BunqAccount,
|
||||
monetaryAccount: BunqMonetaryAccount
|
||||
): RequestInquiryBuilder {
|
||||
return new RequestInquiryBuilder(bunqAccount, monetaryAccount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for creating request inquiries
|
||||
*/
|
||||
export class RequestInquiryBuilder {
|
||||
private bunqAccount: BunqAccount;
|
||||
private monetaryAccount: BunqMonetaryAccount;
|
||||
private options: any = {};
|
||||
|
||||
constructor(bunqAccount: BunqAccount, monetaryAccount: BunqMonetaryAccount) {
|
||||
this.bunqAccount = bunqAccount;
|
||||
this.monetaryAccount = monetaryAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount
|
||||
*/
|
||||
public amount(value: string, currency: string = 'EUR'): this {
|
||||
this.options.amountInquired = { value, currency };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counterparty by IBAN
|
||||
*/
|
||||
public fromIban(iban: string, name?: string): this {
|
||||
this.options.counterpartyAlias = {
|
||||
type: 'IBAN',
|
||||
value: iban,
|
||||
name
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counterparty by email
|
||||
*/
|
||||
public fromEmail(email: string, name?: string): this {
|
||||
this.options.counterpartyAlias = {
|
||||
type: 'EMAIL',
|
||||
value: email,
|
||||
name
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counterparty by phone number
|
||||
*/
|
||||
public fromPhoneNumber(phoneNumber: string, name?: string): this {
|
||||
this.options.counterpartyAlias = {
|
||||
type: 'PHONE_NUMBER',
|
||||
value: phoneNumber,
|
||||
name
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the description
|
||||
*/
|
||||
public description(description: string): this {
|
||||
this.options.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow bunq.me
|
||||
*/
|
||||
public allowBunqme(allow: boolean = true): this {
|
||||
this.options.allowBunqme = allow;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set merchant reference
|
||||
*/
|
||||
public merchantReference(reference: string): this {
|
||||
this.options.merchantReference = reference;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set minimum age requirement
|
||||
*/
|
||||
public minimumAge(age: number): this {
|
||||
this.options.minimumAge = age;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require address
|
||||
*/
|
||||
public requireAddress(type: 'BILLING' | 'SHIPPING' | 'BILLING_SHIPPING'): this {
|
||||
this.options.requireAddress = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow tips
|
||||
*/
|
||||
public allowTips(allow: boolean = true): this {
|
||||
this.options.wantTip = allow;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow lower amount
|
||||
*/
|
||||
public allowLowerAmount(allow: boolean = true): this {
|
||||
this.options.allowAmountLower = allow;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow higher amount
|
||||
*/
|
||||
public allowHigherAmount(allow: boolean = true): this {
|
||||
this.options.allowAmountHigher = allow;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set redirect URL
|
||||
*/
|
||||
public redirectUrl(url: string): this {
|
||||
this.options.redirectUrl = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the request inquiry
|
||||
*/
|
||||
public async create(): Promise<BunqRequestInquiry> {
|
||||
if (!this.options.amountInquired) {
|
||||
throw new Error('Amount is required');
|
||||
}
|
||||
if (!this.options.counterpartyAlias) {
|
||||
throw new Error('Counterparty is required');
|
||||
}
|
||||
if (!this.options.description) {
|
||||
throw new Error('Description is required');
|
||||
}
|
||||
|
||||
const request = new BunqRequestInquiry(this.bunqAccount, this.monetaryAccount);
|
||||
await request.create(this.options);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request response class for responding to payment requests
|
||||
*/
|
||||
export class BunqRequestResponse {
|
||||
private bunqAccount: BunqAccount;
|
||||
private monetaryAccount: BunqMonetaryAccount;
|
||||
|
||||
constructor(bunqAccount: BunqAccount, monetaryAccount: BunqMonetaryAccount) {
|
||||
this.bunqAccount = bunqAccount;
|
||||
this.monetaryAccount = monetaryAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a request
|
||||
*/
|
||||
public async accept(
|
||||
requestResponseId: number,
|
||||
amountResponded?: IBunqAmount,
|
||||
description?: string
|
||||
): Promise<number> {
|
||||
await this.bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
const response = await this.bunqAccount.getHttpClient().put(
|
||||
`/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/request-response/${requestResponseId}`,
|
||||
{
|
||||
amount_responded: amountResponded,
|
||||
status: 'ACCEPTED',
|
||||
description: description
|
||||
}
|
||||
);
|
||||
|
||||
if (response.Response && response.Response[0] && response.Response[0].Id) {
|
||||
return response.Response[0].Id.id;
|
||||
}
|
||||
|
||||
throw new Error('Failed to accept request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject a request
|
||||
*/
|
||||
public async reject(requestResponseId: number): Promise<void> {
|
||||
await this.bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
await this.bunqAccount.getHttpClient().put(
|
||||
`/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/request-response/${requestResponseId}`,
|
||||
{
|
||||
status: 'REJECTED'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* List incoming payment requests
|
||||
*/
|
||||
public async listIncoming(options?: IBunqPaginationOptions): Promise<any[]> {
|
||||
await this.bunqAccount.apiContext.ensureValidSession();
|
||||
|
||||
const response = await this.bunqAccount.getHttpClient().list(
|
||||
`/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/request-response`,
|
||||
options
|
||||
);
|
||||
|
||||
return response.Response || [];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user