Implementación
  • 19 Jun 2024
  • 10 Minutos para leer

Implementación


Resumen del artículo

Headless checkout de OrkestaPay

Ya teniendo instanciado el script de OrkestaPay, se debe generar una instancia de OrkestaPayCard, el cuál permite instanciarlo de varias maneras:

Inicializar tarjeta mediante referencias de los inputs del DOM

Para referenciar los inputs del formulario de tarjeta, se pueden referenciar mediante el ID del elemento o mediante la referencia del input (opción recomendada).

Las referencias de los inputs definidas son:

  • card_number (Requerido): Puede ser la referencia de tipo HTMLInputElement o el ID como string.

  • expiration_date (Requerido): Puede ser la referencia de tipo HTMLInputElement, el ID como string; o si se requiere mantener separados en inputs individuales el mes y año, se puede pasar un objeto con las propiedades:

  • expiration_month (Requerido): Puede ser la referencia de tipo HTMLInputElement o el ID como string.

  • expiration_year (Requerido): Puede ser la referencia de tipo HTMLInputElement o el ID como string.

  • verification_code (Requerido): Puede ser la referencia de tipo HTMLInputElement o el ID como string.

  • holder_name (Opcional): Puede ser la referencia de tipo HTMLInputElement o el ID como string. Importante: Si no se le pasa la referencia del holder name, éste dato debe ser proporcionado durante la tokenización que será descrita en el apartado Tokenizar una tarjeta.

  • holder_last_name (Opcional): Puede ser la referencia de tipo HTMLInputElement o el ID como string.

Ejemplo de inicialización mediante las referencias de los inputs del DOM (recomendado) usando un sólo input para la fecha de expiración:

async function createOrkestaPayCard() {
    const card_number = document.getElementById('card-number');
    const expiration_date = document.getElementById('card-expiration');
    const verification_code = document.getElementById('card-verification-code');
    const holder_name = document.getElementById('holder-name');
    const holder_last_name = document.getElementById('holder-last-name');

    const orkestapay_card = await orkestapay.createCard({
        card_number,
        expiration_date,
        verification_code,
        holder_name,
        holder_last_name,
    });

    return orkestapay_card;
}


Ejemplo de inicialización mediante los IDs de los inputs del DOM usando un inputs separados para la fecha de expiración y sin la configuración de promociones:

async function createOrkestaPayCard() {
    const card_number = 'card-number';
    const expiration_month = 'card-expiration-month';
    const expiration_year = 'card-expiration-year';
    const verification_code = 'card-verification-code';
    const holder_name = 'holder-name';
    const holder_last_name = 'holder-last-name';

    const orkestapay_card = await orkestapay.createCard({
        card_number,
        expiration_date: {
            expiration_month,
            expiration_year,
        },
        verification_code,
        holder_name,
        holder_last_name,
    });

    return orkestapay_card;
}

Ejemplo de inicialización sin parámetros y ejecución del método mount para referenciar los inputs del DOM

También se puede generar la instancia de la tarjeta sin parámetros y posteriormente ejecutar el método mount, en donde le proporcionas dichas referencias:

async function createOrkestaPayCard() {
    const orkestapay_card = await orkestapay.createCard();

    const card_number = document.getElementById('card-number');
    const expiration_month = document.getElementById('card-expiration-month');
    const expiration_year = document.getElementById('card-expiration-year');
    const verification_code = document.getElementById('card-verification-code');

    await orkestapay_card.mount({
        card_number,
        expiration_date: {
            expiration_month,
            expiration_year,
        },
        verification_code,
    });

    return orkestapay_card;
}


Ejemplo de inicialización sin parámetros sin la ejecución del método mount para referenciar los inputs del DOM

También se puede generar una instancia de OrkestaPayCard sin necesidad de pasarle las referencias de los inputs. Para pasarle los datos de la tarjeta, se utiliza el método createToken que se describirá en el apartado Tokenizar una tarjeta.

async function createOrkestaPayCard() {
  const orkestapay_card = await orkestapay.createCard();
  return orkestapay_card;
}

Tokenizar una tarjeta

La tokenización de una tarjeta depende en medida de si se le agregaron las referencias de los inputs del formulario de la tarjeta o no, y de si se le agregó la referencia del holder name o si se le va a pasar durante la tokenización.

Para crear la tokenización se requiere un objeto opcional (dependiendo de cómo se configuró la instancia de OrkestaPayCard) con las siguientes propiedades:

  • card (Opcional): Es un objeto que será requerido cuando el holder name no fue proporcionado desde la referencia a un input, o cuando no se haya usado ninguna referencia a los input del formulario de tarjeta:

  • card_number (Opcional/Requerido): Número de la tarjeta en string, es necesario únicamente cuando no se referenció el input del formulario de la tarjeta correspondiente.

  • expiration_date (Opcional/Requerido): Fecha de expiración en cualquiera de los formatos mm/yy o mm/yyyy en string, es necesario únicamente cuando no se referenció el input del formulario de la tarjeta correspondiente.

  • verification_code (Opcional/Requerido): Código de verificación en string, es necesario únicamente cuando no se referenció el input del formulario de la tarjeta correspondiente.

  • holder_name (Requerido): Sólo es requerido cuando es la única propiedad requerida que no fue referenciada mediante su input del formulario de la tarjeta correspondiente.

  • holder_last_name (Opcional).

  • customer_id (Opcional): Sólo cuando se haya creado/obtenido previamente el customer mediante la API de OrkestaPay.

  • one_time_use (Opcional): Valor de tipo boolean. Cuando no se tiene la propiedad customer_id siempre debe ir en true.

Se deben tomar en cuenta las siguientes variables para los ejemplos de tokenización de este apartado:

const is_sandbox = true;
const merchant_id = '{YOUR_MERCHANT_ID}';
const public_key = '{YOUR_PUBLIC_KEY_OR_DEVICE_KEY}';
const orkestapay = initOrkestaPay({ is_sandbox, merchant_id, public_key });


const card_number_id = 'card-number';
const expiration_date_id = 'card-expiration';
const expiration_month_id = 'card-expiration-month';
const expiration_year_id = 'card-expiration-year';
const verification_code_id = 'card-verification-code';
const holder_name_id = 'holder-name';
const holder_last_name_id = 'holder-last-name';


const card_number = document.getElementById(card_number_id);
const expiration_date = document.getElementById(expiration_date_id);
const expiration_month = document.getElementById(expiration_month_id);
const expiration_year = document.getElementById(expiration_year_id);
const verification_code = document.getElementById(verification_code_id);
const holder_name = document.getElementById(holder_name_id);
const holder_last_name = document.getElementById(holder_last_name_id);

Ejemplos para tokenizar tarjetas

En el siguiente ejemplo se crea un método de pago tokenizando una tarjeta que tiene la referencia al número de tarjeta, fecha de expiración usando un sólo input, código de verificación, nombre del dueño de la tarjeta, segundo nombre del dueño de la tarjeta y la configuración de las promociones. Como no se le está pasando ningún parámetro, mandara un warning en consola en donde indique que la propiedad one_time_use se pasará a true.

(async function tokenize() {
  const orkestapay_card = await orkestapay.createCard({
    card_number,
    expiration_date,
    verification_code,
    holder_name,
    holder_last_name,
  });

  const payment_method = await orkestapay_card.createToken();
})();


En el siguiente ejemplo se crea un método de pago tokenizando una tarjeta que tiene la referencia al número de tarjeta, fecha de expiración usando un sólo input, código de verificación, nombre del dueño de la tarjeta, segundo nombre del dueño de la tarjeta y la configuración de las promociones. Se pasa la propiedad one_time_use con valor true ya que no se le está proporcionando el customer_id y por ende no se puede guardar para usos futuros.

(async function tokenize() {
    const orkestapay_card = await orkestapay.createCard({
        card_number,
        expiration_date,
        verification_code,
        holder_name,
        holder_last_name,
    });

    const one_time_use = true;
    const payment_method = await orkestapay_card.createToken({ one_time_use });
})();


En el siguiente ejemplo se crea un método de pago tokenizando una tarjeta que tiene la referencia al número de tarjeta, fecha de expiración usando inputs separados para el mes y año, código de verificación y la configuración de las promociones. Se pasa la propiedad one_time_use con valor false ya que sí se le está proporcionando el customer_id y se puede guardar este método de pago para usos futuros para este customer en específico.

(async function tokenize() {
    const orkestapay_card = await orkestapay.createCard();

    await orkestapay_card.mount({
        card_number: card_number_id,
        expiration_date: {
            expiration_month: expiration_month_id,
            expiration_year: expiration_year_id,
        },
        verification_code: verification_code_id,
    });

    const holder_name = 'John Doe';
    const card = { holder_name };
    const one_time_use = false;
    const customer_id = '569637be-010c-4790-a2da-9c30bd9374c5';

    const payment_method = await orkestapay_card.createToken({
        card,
        customer_id,
        one_time_use,
    });
})();


En el siguiente ejemplo no se referencia a los inputs del formulario de tarjeta, en su lugar, se le pasan dichos datos durante la tokenización:

(async function tokenize() {
    const orkestapay_card = await orkestapay.createCard();

    const card_number = '4242 4242 4242 4242';
    const expiration_date = '12/28';
    const verification_code = '123';
    const holder_name = 'John';
    const holder_last_name = 'Doe';

    const card = {
        card_number,
        expiration_date,
        verification_code,
        holder_name,
        holder_last_name,
    };

    const one_time_use = false;
    const customer_id = '569637be-010c-4790-a2da-9c30bd9374c5';

    const payment_method = await orkestapay_card.createToken({
        card,
        customer_id,
        one_time_use,
    });
})();


Gestionar las validaciones de las referencias de los inputs del formulario de tarjeta

Cuando le pasas las referencias de los inputs del formulario de tarjeta, se validan en tiempo real si los valores ingresados son correctos o no, esto por cada referencia.

Partiendo de que ya se inicializó una instancia de OrkestaPayCard:

const is_sandbox = true;
const merchant_id = '{YOUR_MERCHANT_ID}';
const public_key = '{YOUR_PUBLIC_KEY_OR_DEVICE_KEY}';
const orkestapay = initOrkestaPay({ is_sandbox, merchant_id, public_key });
let orkestapay_card;

(async function createOrkestaPayCard() {
  orkestapay_card = await orkestapay.createCard();
})();

Tenemos los siguientes eventos:

  • orkestapay_card.card_number.errors$

  • orkestapay_card.expiration_date.errors$

  • orkestapay_card.verification_code.errors$

  • orkestapay_card.holder_name.errors$

  • orkestapay_card.holder_last_name.errors$

Donde cada uno es un observable que estará emitiendo los errores que se detecten cuando el usuario esté ingresando sus datos de tarjeta, en el siguiente ejemplo se muestra cómo subscribirte a los errores de card_number:

orkestapay_card.card_number.errors$.subscribe((error) => {
  if (error) console.error(error.code, error.message, error);
});

En el apartado de Modelos y entidades de error se describe el tipo de errores disponibles.

Finalizar la instancia de OrkestaPayCard

Cuando ya no se necesita la instancia de OrkestaPayError, se debe desmontar para que complete y cierre todos los eventos generados, para ello se usa el método unmount:

(async function destroyCard() {
  await orkestapay_card.unmount();
})();

Importante: Aunque no se hayan pasado las referencias de los inputs del formulario de tarjeta, es importante desmontar la instancia de OrkestaPayCard.

Modelos y entidades

Modelos y entidades de OrkestaPayCard

Clase OrkestaPayCard

class OrkestaPayCard {
  public readonly card_number!: OrkestaPayCardNumber;
  public readonly expiration_date!: OrkestaPayCardExpirationDate;
  public readonly verification_code!: OrkestaPayCardVerificationCode;
  public readonly holder_name!: OrkestaPayHolderName;
  public readonly holder_last_name!: OrkestaPayHolderLastName;


  public mount(mount_params: MountCardParams): Promise<boolean>;
  public isAlreadyMounted(): boolean;
  public validate(): void;
  public isValid(): boolean;
  public isInvalid(): boolean;
  public isCompleted(): boolean;
  public unmount(): Promise<boolean>;
  public createToken(params?: CreateTokenParams): Promise<PaymentMethodCard>;
}

Clase MountCardParams

class MountCardParams {
  public card_number!: HTMLInputElement | string;
  public expiration_date!: MountCardExpirationParams | HTMLInputElement | string;
  public verification_code!: HTMLInputElement | string;
  public holder_name?: HTMLInputElement | string;
  public holder_last_name?: HTMLInputElement | string;
  public promotions_params!: MountCardPromotionParams;
}

Clase MountCardExpirationParams

class MountCardExpirationParams {
  public expiration_month!: HTMLInputElement | string;
  public expiration_year!: HTMLInputElement | string;
}

Clase MountCardPromotionParams

class MountCardPromotionParams {
  public currency!: string;
  public total_amount!: number | string;
}

Clase CreateTokenParams

class CreateTokenParams {
  public card?: CreateTokenCardParams;
  public one_time_use?: boolean;
  public customer_id?: string;
}

Clase CreateTokenCardParams

class CreateTokenCardParams {
  public card_number?: string;
  public expiration_date?: string;
  public verification_code?: string;
  public holder_name!: string;
  public holder_last_name?: string;
}

Clase OrkestaPayCardNumber

class OrkestaPayCardNumber {
  public readonly field_name: string;
  public readonly promotions$: Observable<CardPromotion[]>;
  public readonly errors$: Observable<OrkestaPayError | null>;

  public mount(mount_params: OrkestaPayCardNumberMountParams): Promise<boolean>;
  public isAlreadyMounted(): boolean;
  public validate(): void;
  public isValid(): boolean;
  public isInvalid(): boolean;
  public isCompleted(): boolean;
  public unmount(): Promise<boolean>;
  public getErrors(): OrkestaPayError | null;
  public mountPromotions(promotions_params: MountCardPromotionParams): Promise<boolean>;
  public getBin(): string;
  public getLastFour(): string;
  public setCardNumber(card_number: string): void;
}

Clase OrkestaPayCardNumberMountParams

class OrkestaPayCardNumberMountParams {
  card_number!: HTMLInputElement | string;
  promotions_params!: MountCardPromotionParams;
}

Clase CardPromotion

class CardPromotion {
  public type!: string;
  public installments!: number[];
}

Clase OrkestaPayCardExpirationDate

class OrkestaPayCardExpirationDate {
  public readonly field_name: string;
  public readonly errors$: Observable<OrkestaPayError | null>;

  public mount(mount_params: HTMLInputElement | string): Promise<boolean>;
  public isAlreadyMounted(): boolean;
  public validate(): void;
  public isValid(): boolean;
  public isInvalid(): boolean;
  public isCompleted(): boolean;
  public unmount(): Promise<boolean>;
  public getErrors(): OrkestaPayError | null;
  public getSeparator(): string;
  public setSeparator(separator: string): void;
  public getDate(): string;
  public setDate(expiration_date: OrkestaPayCardExpirationDateParams | string): void;
  public getMonth(): string;
  public setMonth(month: string): void;
  public getYear(): string;
  public setYear(year: string): void;
}

Clase OrkestaPayCardExpirationDateParams

class OrkestaPayCardExpirationDateParams {
  public expiration_month!: string;
  public expiration_year!: string;
}

Clase OrkestaPayCardVerificationCode

class OrkestaPayCardVerificationCode {
  public readonly field_name: string;
  public readonly errors$: Observable<OrkestaPayError | null>;

  public mount(mount_params: HTMLInputElement | string): Promise<boolean>;
  public isAlreadyMounted(): boolean;
  public validate(): void;
  public isValid(): boolean;
  public isInvalid(): boolean;
  public isCompleted(): boolean;
  public unmount(): Promise<boolean>;
  public getErrors(): OrkestaPayError | null;
  public setVerificationCode(verification_code: string): void;
}

Clase OrkestaPayHolderName

class OrkestaPayHolderName {
  public readonly field_name: string;
  public readonly errors$: Observable<OrkestaPayError | null>;

  public mount(mount_params: HTMLInputElement | string): Promise<boolean>;
  public isAlreadyMounted(): boolean;
  public validate(): void;
  public isValid(): boolean;
  public isInvalid(): boolean;
  public isCompleted(): boolean;
  public unmount(): Promise<boolean>;
  public getErrors(): OrkestaPayError | null;
  public getHolderName(): string;
  public setHolderName(holder_name: string): void;
}

Clase OrkestaPayHolderLastName

class OrkestaPayHolderLastName {
  public readonly field_name: string;
  public readonly errors$: Observable<OrkestaPayError | null>;

  public mount(mount_params: HTMLInputElement | string): Promise<boolean>;
  public isAlreadyMounted(): boolean;
  public validate(): void;
  public isValid(): boolean;
  public isInvalid(): boolean;
  public isCompleted(): boolean;
  public unmount(): Promise<boolean>;
  public getErrors(): OrkestaPayError | null;
  public getHolderLastName(): string;
  public setHolderLastName(holder_last_name: string): void;
}

Modelos y entidades de error

Clase OrkestaPayError

class OrkestaPayError extends Error {
    public override readonly name: string = this.constructor.name;

    constructor(public readonly code: ORKESTAPAY_CARD_FORM_VALIDATOR_ERROR, message: string) {
        super(message);
    }
}

Enumerador ORKESTAPAY_CARD_FORM_VALIDATOR_ERROR

enum ORKESTAPAY_CARD_FORM_VALIDATOR_ERROR {
  REQUIRED = 'REQUIRED',
  MIN_LENGTH = 'MIN_LENGTH',
  MAX_LENGTH = 'MAX_LENGTH',
  INVALID_LENGTH = 'INVALID_LENGTH',
  INVALID_FORMAT = 'INVALID_FORMAT',
  EXPIRED = 'EXPIRED',
  INVALID = 'INVALID',
}


¿Te ha sido útil este artículo?

What's Next