Zenki
Zenki Principal Habilitar modo claro/oscuro Habilitar modo claro/oscuro Habilitar modo claro/oscuro Regresar a la página principal

Integración con nuestra librería de Angular

Al darle click al botón Continuar, se mostrará tu zenkipayKey y un snippet de código que debes copiar y/o adaptar en tu sitio web, dicho snippet trae un ejemplo de la información requerida para poder realizar un pago.

angular

En tu proyecto Angular, instala la versión adecuada de @zenkipay-pkg/angular, para ello puedes revisar la lista de versiones aquí.

Para la versión más actual, ejecuta en una terminal en el directorio root de nuestro proyecto:

1
npm i @zenkipay-pkg/angular

Importante: En nuestra dependencia usamos la versión de rxjs que usa la versión de Angular seleccionada, si tu versión de rxjs no es la que trae por defecto tu versión de Angular puede que te dé algunos errores de compatibilidad, para ello puedes ir probando entre versiones acorde a tu versión de rxjs.

Ya que tienes instalada nuestra dependencia, procede a agregarlo a nuestro módulo de Angular, para ello necesitas pasarle en configuración nuestro zenkipayKey. A continuación se muestra un ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { ZenkipayModule } from "@zenkipay-pkg/angular";

import { AppComponent } from "./app.component";

@NgModule({
  bootstrap: [AppComponent],
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    ZenkipayModule.forRoot({
      zenkipayKey:
        "e77e5b6662532432e9179ff4d33fe364ec88aacf9240e5e7673e474255e4a90c",
    }),
  ],
})
export class AppModule {}

Una vez instalado y configurado nuestro módulo, tienes a tu disposición el uso del componente zenkipay-button que inserta el botón de pago de Zenkipay y nuestro servicio ZenkipayService que te permite consultar si tu comerciante tiene habilitado el descuento crypto love y su porcentaje, o no; también te permite abrir la modal de pago. Dicho componente y servicio serán descritos a continuación:

Componente zenkipay-button

El selector de nuestro componente es zenkipay-button, éste cuenta con una serie de entradas y salidas, descritas en las siguientes tablas:

Entrada Tipo Descripción
paymentDetails PaymentDetails Requerido, este objeto contiene la información necesaria para realizar el pago.
style Style Opcional, con esta entrada puedes modificar los estilos del botón.
Salida Tipo Descripción
zenkiPayment ZenkiPayment Emite cada actualización de eventos de la modal de pago.
error Error Emite un evento cuando ocurre un error, así como su detalle.

Servicio ZenkipayService

Puedes inyectarlo en el constructor de tus componentes/servicios como cualquier otro servicio de Angular, la definición de sus métodos aparece a continuación:

1
2
3
4
5
6
7
declare class ZenkipayService {
  public getDiscountPercentage(
    paymentDetails: PaymentDetails
  ): Observable<number | null>;

  public pay(paymentDetails: PaymentDetails): Observable<ZenkiPayment>;
}

Método getDiscountPercentage

Con este método puedes consultar si tu comerciante tiene el descuento crypto love habilitado, para ello necesitas pasarle como parámetro un objeto de tipo PaymentDetails, y éste te retornará mediante un observable el porcentaje de tu descuento, en caso de que no tenga habilitado el descuento retornará null.

Método pay

Con este método puedes abrir la modal para realizar un pago, para ello necesitas pasarle como parámetro un objeto de tipo PaymentDetails, éste retorna un observable que puede emitir varios eventos de tipo ZenkiPayment, por ello aconsejamos que se guarde la referencia de esa subscripción y se desuscriba en cuanto termine el proceso de ese pago en particular.

Pago de pruebas

Ya que tengas preparada tu integración, procede a realizar un pago de pruebas desde tu sitio, para ello da click en el botón Haz un pago de prueba con datos firmados, lo que te mostrará una modal como la siguiente:

common-test-01

Para realizar tu pago puedes seguir nuestra guía de pagos aquí.

Realiza tu primer pago

Ya que hayas realizado correctamente tu pago de pruebas, se te mostrará un mensaje de que hemos confirmado tu primer pago de integración.

common-test-02

Prueba rápida

Si aún no has generado tus llaves pública y privada, puedes continuar con la selección de tus criptomonedas aquí.

Si ya generaste tus llaves pública y privada, y firmaste tu Purchase Data, debes continuar con tu configuración de KYC.

Integración completa

Ya que hayas realizado tu prueba con tus datos firmados con tus llaves, podemos continuar con tu selección de criptomonedas.

Definición de entidades

Styles

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Style {
  theme?: Theme;
  shape?: Shape;
  size?: Size;
  expand?: Expand;
}

type Theme = "default" | "dark" | "light";

type Shape = "default" | "pill" | "square";

type Size = "default" | "sm" | "lg";

type Expand = "default" | "block";

PaymentDetails

1
2
3
4
class PaymentDetails {
  purchaseData!: string; // PurchaseData stringified
  purchaseSignature!: string;
}

PurchaseData

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class PurchaseData {
  country?: string;
  shopperCartId?: number | string;
  merchantOrderId?: number | string;
  shopperEmail?: string;
  purchaseSummary!: PurchaseSummary;
  items!: PurchaseItem[];
  metadata?: Metadata;
}

class PurchaseSummary {
  currency!: string;
  totalItemsAmount!: number | string;
  shipmentAmount!: number | string;
  subtotalAmount!: number | string;
  taxesAmount!: number | string;
  localTaxesAmount!: number | string;
  importCosts!: number | string;
  discountAmount!: number | string;
  additionalCharges?: AdditionalCharges;
  grandTotalAmount!: number | string;
}

class AdditionalCharges {
  [key: string]: number | string;
}

class PurchaseItem {
  itemId?: number | string;
  quantity!: number | string;
  price!: number | string;
  productName!: string;
  productDescription?: string;
  thumbnailUrl?: string;
  metadata?: Metadata;
}

class Metadata {
  [key: string]: number | string;
}

ZenkiPayment

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class ZenkiPayment {
  status!: POST_MSG_TYPE;
  isCompleted!: boolean;
  data?: DoneMsg | null;
}

enum POST_MSG_TYPE {
  ERROR = "error",
  CANCEL = "cancel",
  CLOSE = "close",
  DONE = "done",
}

class DoneMsg {
  orderId!: string;
}

Ejemplos

A continuación se muestra un ejemplo de cómo puedes usar nuestro componente y nuestro servicio:

app.component.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<zenkipay-button
  [style]="style"
  [paymentDetails]="paymentDetails"
  (zenkiPayment)="zenkiPayment($event)"
></zenkipay-button>

<button (click)="payWithZenkipay()">
  Pay with Zenkipay
  <ng-container *ngIf="discountPercentage">
    -{{ discountPercentage }}%
  </ng-container>
</button>

app.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { Component, OnInit, OnDestroy } from "@angular/core";
import {
  PaymentDetails,
  Style,
  ZenkiPayment,
  ZenkipayService,
} from "@zenkipay-pkg/angular";
import { Observable, Subscription, switchMap } from "rxjs";

import { YourApiService } from "./services/your-api/your-api.service";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"],
})
export class AppComponent implements OnInit, OnDestroy {
  private readonly _subscriptions: Subscription[] = [];

  private _purchaseData!: string;
  private _purchaseSignature!: string;
  public discountPercentage?: number | null;

  // Optional
  public style: Style = {
    shape: "pill", // Optional
    size: "lg", // Optional
  };

  public get paymentDetails(): PaymentDetails {
    return {
      // * Your purchase data will be the same string used to create the signature
      purchaseData: this._purchaseData,
      purchaseSignature: this._purchaseSignature,
    };
  }

  constructor(
    private readonly _zenkipayService: ZenkipayService,
    private readonly _yourApiService: YourApiService
  ) {}

  public ngOnInit(): void {
    this._yourApiService
      .getPurchaseData()
      .pipe(
        switchMap(
          ({ purchaseData, purchaseSignature }): Observable<number | null> => {
            this._purchaseData = purchaseData;
            this._purchaseSignature = purchaseSignature;
            return this._zenkipayService.getDiscountPercentage(
              this.paymentDetails
            );
          }
        )
      )
      .subscribe((discountPercentage: number | null): void => {
        this.discountPercentage = discountPercentage;
      });
  }

  public ngOnDestroy(): void {
    for (let i = 0; i < this._subscriptions.length; i++) {
      this._subscriptions[i].unsubscribe();
    }
  }

  public zenkiPayment(zenkiPayment: ZenkiPayment): void {
    console.log(zenkiPayment);
  }

  public payWithZenkipay(): void {
    this._subscriptions.push(
      this._zenkipayService
        .pay(this.paymentDetails)
        .subscribe((zenkiPayment: ZenkiPayment): void => {
          console.log(zenkiPayment);
        })
    );
  }
}