パッケージの詳細

seerbit-angular

seerbit59MIT16.0.1
angular, seerbit, payments

readme

seerbit-angular

An Angular 16 Library for SeerBit payment gateway

Features

  • The library enables easy integration with Angular.
  • Integrate as a Component
  • Integrate as a Directive

Getting started

Documentation

The documentation, installation guide, detailed description of the SeerBit API and all of its features is available on the documentation website.

Requirements

  • Angular 16 and higher

Installation

You can use NPM to include the library in your project

NPM

npm install --save seerbit-angular

Inject the library

Import the NgSeerBitModule into your application (most likely your checkout module)

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {NgSeerBitModule} from 'seerbit-angular';

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

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,NgSeerBitModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Implementation in your Application

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'seerbit-anguar-demo';

  PaymentDone(res) {/*event handler with a response after a complete transaction*/
    const {response, closeModal} = res;
    console.log('response', response)
    closeModal();
  }
  PaymentCancel(response) {/*event handler when shopper closes payment modal*/
    console.log(response)
  }

  options = {
       tranref: new Date().getTime(),
       currency: 'NGN',
       description: 'TEST PAYMENT',
       country: 'NG',
       email: 'samsmart@emaildomain.com',
       mobile_no: '08011111111',
       full_name: 'Sam Smart',
       amount: 2000,
       setAmountByCustomer: false, 
       close_prompt: false,
       close_on_success: false,
       callbackurl: '', // Replace this with URL available on the WWW
       public_key: 'public_key_from_your_merchant_dashboard', // replace this with your own public key from your Merchant Dashboard
       customization: {
                theme: {
                  border_color: "#000000",
                  background_color: "#004C64",
                  button_color: "#0084A0",
                },
                payment_method: ["card", "account", "transfer", "wallet", 'ussd'],
                display_fee: true, // false
                logo: "logo_url || base64", 
              },
      tokenize: false,
      planId: ""
  };
}

Implementation in your Component Template

As a Component

<seerbit-ng class="your-custom-class" (callback)="PaymentDone($event)" (close)="PaymentCancel($event)" [options]="options">
Trigger Payment Modal as a Component
</seerbit-ng>

A caveat for implementing as a component requires your styling to available globally for the component to inherit them.

As a Directive

<button class="your-custom-class" seerbit-ng (callback)="PaymentDone($event)" (close)="PaymentCancel($event)" [options]="options">
Trigger Payment Modal as a Component
</button>

Examples

You can also check the projects/seerbit-anguar-demo folder in this repository for more examples of usage.

A Shopping cart example

<strong>App Component</strong>
import { Component } from '@angular/core';
import {PRODUCTS} from './mock.products';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'seerbit-anguar-demo';
  cart = [...PRODUCTS];
  cart_total = 0;
  cart_total_cost = 0;
  available_quantities = [1, 2, 3];

  options = {
    tranref: new Date().getTime(),
    currency: "NGN",
    description: "TEST",
    country: "NG",
    email: "test@emaildomain.com",
    mobile_no: "08011111111",
    full_name: "test test",
    amount: this.cart_total_cost,
    setAmountByCustomer: false,
    close_prompt: false,
    close_on_success: false,
    callbackurl: "", // Replace this with URL available on the WWW
    public_key: "public_key_from_your_merchant_dashboard", // replace this with your own public key from your Merchant Dashboard
    customization: {
      theme: {
        border_color: "#4c4c4c",
        background_color: "#61bc6e",
        button_color: "#0000000",
      },
      // payment_method: ["card", "account", "transfer", "wallet", 'ussd'],
      // logo: "logo_url || base64",
    },
    tokenize: false,
    planId: ""
  };

  PaymentDone(response) {
    console.log('callback');
    console.log(response); /*response of transaction*/
  }
  PaymentCancel(response) {
    console.log('cancel');
    console.log(response);
  }

  PaymentPayloadValidationError(error) {
    console.log('payload validation error');
    console.log(error);
  }

  cartTotalCost = () => {
    let total = 0;
    this.cart.map(item => {
      total += item.price * item.qty;
    });
    this.cart_total_cost = total;
    this.options.amount = total;

  }

  cartTotal = () => {
    let total = 0;
    this.cart.map( item => { total = total + Math.floor(item.qty);  });
    this.cartTotalCost();
    return total;
  }

  removeItem(product) {
    this.cart = this.cart.filter( item => item.id != product.id);
  }

  updateCart(product, qty: number) {
    this.cart.map( item => {
      item.id == product.id ? item.qty = Math.floor(qty) : null;
      return item;
    }
    );
    this.cartTotalCost();

  }
}
<strong>Product mock data and product type</strong>
export class Product {
    id: number;
    name: string;
    description:string;
    price:number;
    qty:number
  }
import { Product } from './product';

export const PRODUCTS: Product[] = [
  { id: 11, name: 'Product 1', price:4000, description:'A description of product 1',qty:1 },
  { id: 12, name: 'Product 2', price:8000, description:'A description of product 2',qty:1 },
];
<strong>Component Template</strong>
<div class="center-wrapper">
    <div class="content">
    <nav>
        <a href="#" class="menu">Menu</a>
        <h1 class="logo">demo Shop</h1>
        <div class="icons">
            <i class="fas fa-search"></i>
            <i class="fas fa-shopping-bag"></i><span style="margin-left: 0.3rem;">{{cartTotal()}}</span>
        </div>
    </nav>
    <div class="top-bar">
        <i class="fas fa-arrow-left"></i>
        <span>Continue shopping</span>
    </div>
    <div class="bag">
        <p class="bag-head"><span style="text-transform: uppercase">Your Bag</span> - {{cartTotal()}} item</p>
    </div>
    <div class="bag-product" *ngFor="let product of cart">
        <div class="description">

            <h1>{{product.name}}</h1>
            <p class="description-text">{{product.description}}.</p>
            <h2>N{{product.price}}</h2>
            <div class="quantity-wrapper">
                <div>
                    <label for="quantity" style="margin-right: 0.5rem;">Quantity:</label>
                    <select name="quantity" style="margin-bottom: 1rem;" (change)="updateCart(product, $event.target.value)">
            <option value disabled>Please select</option>
                        <option value={{qty}} [selected]="qty == product.qty" *ngFor="let qty of available_quantities">{{qty}}</option>

                    </select>
                </div>
                <button class="btn-remove" (click)="removeItem(product)">Remove</button>
            </div>
        </div>
    </div>
    <div class="bag-total">
        <div class="subtotal">
            <p class="small">Subtotal:</p>
            <p class="small">N{{cart_total_cost}}</p>
        </div>
        <div class="delivery">
            <p class="small">Delivery (Standard - 2 working days):</p>
            <p class="small">Free</p>
        </div>
        <div class="total">
            <h3>Total:</h3>
            <h3>N{{cart_total_cost}}</h3>
        </div>
        <button class="btn-go-checkout" seerbit-ng (callback)="PaymentDone($event)" (close)="PaymentCancel($event)"
    [options]="options">
            <i class="fas fa-lock"></i>
            <span>Pay (Button as a Directive)</span>
        </button>
        <seerbit-ng class="btn-go-checkout" (callback)="PaymentDone($event)" (close)="PaymentCancel($event)" [options]="options">
            Pay (Button as a Component)
          </seerbit-ng>

    </div>

</div>
</div>
<strong>Component Template CSS</strong>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  html,
  body {
    height: 100%;
    font-size: 16px;
    font-weight: 400;
  }

  .center-wrapper {
    padding: 0.5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 100%;
  }

  .content {
    margin: 0 auto;
    max-width: 600px;
    width: 500px;
    border: 1px solid lemonchiffon;
    background: white;
  }

  nav,
  .top-bar,
  .bag,
  .bag-total,
  .help {
    padding: 0.5rem 1rem;
  }

  nav,
  a,
  .btn-go-checkout {
    color: white;
  }

  nav {
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    align-items: center;
    background: #03375E;
  }

  a {
    padding: 0.2rem 0.5rem;
    border: 2px solid white;
    text-decoration: none;
  }

  .logo {
    font-family: "Space Mono", sans-serif;
  }

  .logo,
  button {
    text-transform: uppercase;
  }

  .top-bar,
  .bag-head::after,
  .bag-total::before {
    background: whitesmoke;
  }

  .bag-head::after,
  .bag-total::before,
  .btn-remove {
    display: block;
  }

  .bag-head::after,
  .bag-total::before,
  .description-text{
    margin: 0.5rem 0;
  }

  .bag-head::after,
  .bag-total::before {
    content: "";
    width: 100%;
    height: 3px;
  }

  .muted {
    color: grey;
  }

  h1 {
    font-size: 1rem;
  }

  h2 {
    font-size: .8rem;
  }

  .image {
    width: 40%;
  }
  .image img.product-image {
    max-width: 100%;
  }

  .description {
    padding: 1rem;
    width: 100%;
  }

  select {
    padding: 0.3rem;
    width: 80px;
  }

  select,
  button,
  input[type="text"] {
    height: 20px;
  }

  button {
    cursor: pointer;
    width: 100px;
    background: none;
    border: 2px solid #0D6CB4;
  }

  .quantity-wrapper {
    align-items: flex-start;
    flex-flow: row wrap;
    margin: 1rem 0 0.5rem;
  }

  select {
    width: 50px;
    margin-right: 1rem;
  }

  .bag-product,
  .quantity-wrapper,
  .subtotal,
  .delivery,
  .total {
    display: flex;
    justify-content: space-between;
  }

  .subtotal,
  .delivery,
  input[type="checkbox"],
  .help {
    margin-bottom: 0.5rem;
  }

  .total {
    margin-bottom: 1rem;
  }


  input[type="text"],
  .btn-go-checkout {
    font-size: 1rem;
  }

  input[type="text"] {
    width: calc(100% - 100px - 1rem);
    padding: 0.5rem;
  }

  .btn-go-checkout {
    margin-top: 1rem;
    width: 100%;
    height: 40px;
    background: #0D6CB4;
    box-shadow: 0 3px 6px 2px gainsboro;
  }

Website