Zenki
Zenki Home Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Integration with our Angular library

By clicking the Continue button, your zenkipayKey and a code snippet that you must copy and/or adapt on your website will be displayed, said snippet brings an example of the information required to make a payment.

angular

In your Angular project, install the appropriate version of @zenkipay-pkg/angular , for this you can check the version list here .

For the most current version we execute in a terminal in the root directory of our project:

1
npm i @zenkipay-pkg/angular

Important: In our dependency we use the version of rxjs that uses the selected Angular version, if your version of rxjs is not the one that comes by default with your version of Angular, it may give you some compatibility errors, for this you can try between versions according to your version of rxjs .

Since we have our dependency installed, we proceed to add it to our Angular module, for this we need to pass our zenkipayKey in the configuration. Here is an example:

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

Once you have installed and configured our module, you have at your disposal the use of the zenkipay-button component that inserts the Zenkipay payment button and our ZenkipayService that allows you to check if your merchant has the crypto love discount enabled and its percentage, or not; it also allows you to open the payment modal. Said component and service will be described below:

Zenkipay-button component

The selector of our component is zenkipay-button , it has a series of inputs and outputs, described in the following tables:

Input Type Description
paymentDetails PaymentDetails Required, this object contains the information necessary to make the payment.
style Style Optional, with this input you can modify the styles of the button.
Output Type Description
zenkiPayment ZenkiPayment Emits every event update of the payment modal.
error Error Emits an event when an error occurs, as well as its details.

Servicio ZenkipayService

You can inject it into the constructor of your components/services like any other Angular service, the definition of its methods appears below:

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

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

getDiscountPercentage Method

With this method you can check if your merchant has the crypto love discount enabled, for this you need to pass an object of type href="#paymentdetails"> PaymentDetails as a parameter, and it will will return the percentage of your discount through an observable, in case the discount is not enabled it will return null .

Pay method

With this method you can open the modal to make a payment, for this you need to pass an object of type href="#paymentdetails"> PaymentDetails as a parameter, it returns an observable that can emit several events of type ZenkiPayment , therefore we recommend that you save the reference of that subscription and unsubscribe as soon as the process of that particular payment is finished.

Test payment

Once you have prepared your integration, we proceed to make a test payment from your site, for this we click on the button Make a test payment with signed data , which will show you a modal like the following:

common-test-01

To make your payment you can follow our payment guide here.

Make your first payment

Once you have successfully made your trial payment, you will be shown a message that we have confirmed your first integration payment.

common-test-02

Simple test

If you haven’t generated your public and private keys yet, you can continue with the selection of your cryptocurrencies here.

If you already generated your public and private keys, and sign your Purchase Data, you must continue with your KYC setup.

Full integration

Once you have done your test with your data signed with your keys, we can continue with your selection of cryptocurrencies.

Definition of entities

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

Examples

Below is an example of how you can use our component and our service:

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