npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gapp-checkout

v1.0.10

Published

Mobile Gapp flow for Checkout

Downloads

19

Readme

Checkout GApp Flow

GApp Flow for Checkout

Installation

npm install serino-mobile-gapp-checkout-flow --registry http://miniapp.serino.com:4873/

Changelogs

See the Change logs

Dependecies

  • npm install axios
  • npm install crypto-js

(CheckoutGAppFlow) DataLoad Props

| Prop | Required | Type | Description | | :------------------ | :------- | :------------ | :--------------------------------------------------------------------------------------------------- | | axiosOrder | No | AxiosInstance | set axios instance for order api. Applicable for dataloadType=network-service | | axiosCheckout | No | AxiosInstance | set axios instance for checkout api. Applicable for dataloadType=network-service | | endpoints | No | object | endpoint for checkout api. Applicable for dataloadType=network-service or network-service-config | | baseUrl | No | object | baseurl for getAll endpoint. Applicable for dataloadType=network-service-config | | payload | No | object | payload request. Applicable for dataloadType=network-service or network-service-config | | requestParams | No | object | Applicable for dataloadType=network-service-config | | cancelRequest | No | | Applicable for dataloadType=network-service-config | | timeout | No | | Applicable for dataloadType=network-service-config | | AppKey | No | | Applicable for dataloadType=network-service-config | | token | No | | Applicable for dataloadType=network-service-config | | tokenType | No | | Applicable for dataloadType=network-service-config | | header | No | object | Applicable for dataloadType=network-service-config |

(CheckoutGAppFlow) DataIn Props

| Prop | Required | Type | Description | | :----------------------------- | :------- | :----------------------------------------- | :------------------------------------------------------------------ | | dataLoadType | Yes | network-service,network-service-config | choices what dataLoad should be apply | | constructOrderPayload | Yes | function | function that reconstruct order payload. should return details. | | constructCheckoutPayload | No | function | function that reconstruct checkout payload. should return details. | | initialRouteName | No | string | initialRouteName for StackNavigator | | screens | No | array of objects | modify mini-app and gapp. able to use with the combination of Stack |

(dataLoad > baseUrl) Props

| Prop | Required | Type | Description | | :------------- | :------- | :----- | :-------------------------------------------------------------------------- | | order | No | string | base url for order. Applicable for dataloadType=network-service-config | | checkout | No | string | base url for checkout. Applicable for dataloadType=network-service-config |

(dataLoad > endpoints) Props

| Prop | Required | Type | Description | | :----------------- | :------- | :----- | :-------------------------------------------------------------------------- | | postOrder | No | string | endpoint for order. Applicable for dataloadType=network-service-config | | postCheckout | No | string | endpoint for checkout. Applicable for dataloadType=network-service-config |

(dataLoad > payload) Props

| Prop | Required | Type | Description | | :----------------------------------- | :------- | :-------------- | :----------------------------- | | payee | Yes | string | customer full name | | first_name | Yes | string | customer first name | | last_name | Yes | string | customer last name | | contact_number | Yes | string | customer contact number | | email | Yes | string | customer email | | region | Yes | string | region | | barangay | Yes | string | barangay | | street | Yes | string | street | | building_name | Yes | string | building name | | landmark | Yes | string | nearest landmark | | payment_method | Yes | string | payment method | | subtotal | Yes | number | order subtotal | | discount | Yes | number | voucher discount | | shopee_fee | Yes | number | shopee fee | | delivery_fee | Yes | number | delivery fee | | total_amount | Yes | number | total amount | | items | Yes | array of object | order items | | merchant_transaction_reference | Yes | string | merchant transaction reference | | merchant_processor_id | Yes | number | merchant processor id | | processor | Yes | object | processor | | any property name | No | any | the res payload values. |

(dataLoad > payload > items) Props

| Prop | Required | Type | Description | | :---------------- | :------- | :----- | :---------------------- | | name | Yes | string | product name | | description | Yes | string | product description | | quantity | Yes | number | product quantity | | price | Yes | number | prod' | | uct price | | any property name | No | any | the res payload values. |

(dataLoad > payload > processor) Props

| Prop | Required | Type | Description | | :----------------- | :------- | :----- | :--------------------- | | token | Yes | string | processor token | | redirect_url | Yes | string | processor redirect url |

(dataLoad > payload > processor > redirect_url) Props

| Prop | Required | Type | Description | | :------------ | :------- | :----- | :----------------------------- | | success | Yes | string | processor success redirect url | | failure | Yes | string | processor failure redirect url | | cancel | Yes | string | processor cancel redirect url |

(dataIn > screens) Props

| Prop | Required | Type | Description | | :----------------- | :------- | :------- | :----------------------------------------------------- | | key | No | string | mini-app key | | stackName | No | string | Stack name | | stackOptions | No | object | Stack options | | dataLoad | No | object | mini-app dataLoad. to modify initial and gapp dataLoad | | dataIn | No | object | mini-app dataIn. to modify initial and gapp dataIn | | dataOut | No | function | mini-app dataOut. to modify initial and gapp dataOut |

useViewModel returned value

    'customer-details':{
      dataIn: {
        fullName, // payload > payee
        firstName, // payload > first_name
        lastName, // payload > last_name
        contactNumber, // payload > contact_number
        email,
        region,
        city,
        barangay,
        street,
        buildingName, // payload > building_name
        landmark,
      }
    },
    'order-items': {
      dataIn: {
        items, // order items
      },
    },
    'payment-method': {
      dataIn: {
        label, // payload > payment_method; payment method label
      },
    },
    'order-summary': {
      dataIn: {
        subTotal, // payload > subtotal
        voucherDiscount, // payload > discount
        shopperFee, // payload > shopee_fee
        deliveryFee, // payload > delivery_fee
        grandTotal, // payload > total_amount
      },
    },
    'submit-order': {
      dataIn: {
        disabled, // true or false
        loading, // true or false
      },
      dataOut, // function to apply order & checkout api
    }

Example

Run the following commands

npm run boostrap:setup project by installing all dependencies and pods. npm run example run start: start the Metro server for the example app. npm run example run android: run the example app on Android. npm run example run ios: run the example app on iOS.

Example (dataLoadType="network-service")

axiosCheckout.tsx

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';

const onRequest = (config: AxiosRequestConfig): AxiosRequestConfig => {
  const token = '';
  config.headers.Authorization = `Bearer ${token}`;
  config.headers['x-public-key'] = '';

  return config;
};

const onRequestError = (error: AxiosError): Promise<AxiosError> => {
  return Promise.reject(error);
};

const onResponse = (response: AxiosResponse) => {
  return response.data;
};

const onResponseError = (error: AxiosError): Promise<AxiosError> => {
  return Promise.reject(error.response);
};

const axiosCheckout = axios.create({
  baseURL: 'https://....',
});

axiosCheckout.interceptors.request.use(onRequest, onRequestError);
axiosCheckout.interceptors.response.use(onResponse, onResponseError);

export default axiosCheckout;

Checkout Screen

import * as React from 'react';
import { Button, Text } from 'react-native-paper';
import { CheckoutGAppFlow } from 'serino-mobile-gapp-checkout-flow';
import { GlobalContext } from '../context/GlobalContext';
import axiosCart from '../library/axiosCart';
import axiosCheckout from '../library/axiosCheckout';
import axiosOrder from '../library/axiosOrder';
import OrderItems from '../components/Cart/OrderedItems';
import OrderSummary from '../components/Cart/OrderSummary';
import checkoutJsonStab from '../json-stab/place-order copy.json';

const Checkout = ({ navigation }: any) => {
  const context: any = React.useContext(GlobalContext);

  const reconstructOrderPayload = (values: any) => {
    return {
      orders: [
        {
          action_to_proceed:
            values.action_to_proceed ||
            'Cancel the whole order if any item is out of stock',
          cart_id: values.cart_id || 'a89b5c67-4c19-40e0-a81b-062523a078fb',
          change_for: values.total_amount || '0',
          customer: {
            contact_number: values.contact_number || '+639876546231',
            email: values.email || '[email protected]',
            first_name: values.first_name || 'Ej',
            last_name: values.last_name || 'Dalman',
            reference_1: values.reference_1 || '',
            reference_2: values.reference_2 || '',
            reference_3: values.reference_3 || '',
          },
          fulfillment_type: values.fulfillment_type || 'deliver later',
          items: values.items,
          merchant_reference_id: values.merchant_reference_id || 'market',
          notes: [{ type: 'Order Notes', notes: '' }],
          platform: 'Web',
          platform_details:
            values.platform_details ||
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
          promo_reference_id: '',
          reference_1: '',
          reference_2: '',
          reference_3: '',
          reservation_reference: 'branch_advance_6',
          schedule: '2023-02-28 10:30:0',
          shipping_address: {
            barangay: '',
            city: '',
            details: '',
            full_address:
              'BLK 10 LOT 10 SAMPAGUITA STREET, Bel-Air, Makati, Metro Manila, Philippines',
            landmark: '',
            latitude: 14.554729,
            longitude: 121.0244452,
            pinned_address: 'Makati, Metro Manila, Philippines',
            region: '',
            street: '',
            zip_code: '',
          },
          source: 'Central PH',
          store_reference_id: '6',
        },
      ],
      payment: {
        type: values.payment_method_type,
        option: values.payment_method,
      },
    };
  };

  const payload = {
    ...checkoutJsonStab,
    payment_method_type:
      context.paymentMethod?.parent_type || context.paymentMethod?.type,
    payment_method: context.paymentMethod?.text,
    merchant_processor_id: context.paymentMethod?.id,
    merchant_transaction_reference: 'CENTRAL03411',
    processor: {
      token: '',
      redirect_url: {
        success:
          'https://ordering.com/CENTRAL03411/payment-result?status=sucess',
        failure:
          'https://ordering.com/CENTRAL03411/payment-result?status=failure',
        cancel:
          'https://ordering.com/CENTRAL03411/payment-result?status=cancel',
      },
    },
    items: context?.cartDetails.items.map((d: any) => {
      const customData = JSON.parse(d.custom_data);
      const barcodeDetails = customData
        ? customData.find((c: any) => c.name === 'barcode')
        : {};
      return {
        barcode: barcodeDetails.value || '28400017503',
        description:
          d.itemDescription ||
          '<p>Frito Lay it all start with farm grown potatoes cooked and seasoned to perfection, Then we add just the right balanced of tangly Vinegar. So every Lays potato is perfectly crispy and delicious happiness in every bite.</p>\n<ul>\n<li>No Artificial Flavours</li>\n<li>No Preservatives</li>\n</ul>\n<p><strong>Ingredients:</strong><br />Potatoes, Vegetable Oil (Sunflower, corn and/or Canola Oil), Salt &amp; Vinegar Seasoning (Maltodextrin made from corn, Natural Flavours, Salt, Malic Acid and Vinegar).</p>',
        image:
          d.itemImage ||
          'https://qa-centralmain.s3.ap-southeast-1.amazonaws.com/thumbnails/28400017503-01_8_thumbnail.jpg',
        instructions: d.instructions || '',
        name: d.itemName || 'Lays Salt & Vinegar Potato Chips 184.2g',
        options: '',
        price: d.price ? parseFloat(d.price) : 167.95,
        quantity: d.quantity || 1,
        reference_1: '',
        reference_2: '',
        reference_3: '',
        reference_id: d.itemReferenceId || '24698',
        sku: d.itemSKU || '105146',
        type: d.itemReferenceType || 'basic_product',
        weight: 0,
        weight_price_per_unit: 0,
        weight_uom: '',
      };
    }),
  };
  const public_key = 'pk-8c6a927a-972f-11ed-a8fc-0242ac120002';

  const handleDataOut = (values: any) => {
    console.log('checkout DATAOUT', values);
  };

  const fetchCart = React.useCallback(async () => {
    try {
      const res: any = await axiosCart.get('/cart');
      context.setContext({
        ...context,
        cartDetails: {
          ...context?.cartDetails,
          items: res?.data?.data,
        },
      });
    } catch (err: any) {}
  }, []);

  // life-cycle method to get cart details
  React.useEffect(() => {
    fetchCart();
  }, []);

  return (
    <React.Fragment>
      <CheckoutGAppFlow
        dataLoad={{
          axiosCheckout: axiosCheckout,
          axiosOrder: axiosOrder,
          endpoints: {
            postOrder: '/public/create',
            postCheckout: `/api/public/merchants/${public_key}/checkout`,
          },
          payload: payload,
        }}
        dataIn={{
          dataLoadType: 'network-service',
          constructOrderPayload: reconstructOrderPayload,
        }}
        dataOut={handleDataOut}
      >
        <OrderItems key="order-items" dataIn={{ navigation }} />
        <SelectPaymentMethod
          key="payment-method"
          dataIn={{
            label: context.paymentMethod?.text
              ? context.paymentMethod.text
              : 'Select Payment Method',
          }}
          dataOut={() => {
            navigation.navigate('PaymentMethodFlow');
          }}
        />
        <OrderSummary
          key="order-summary"
          dataIn={{
            subTotal: 0,
            voucherDiscount: 0,
            showPickupDiscount: false,
            pickupDiscount: 0,
            showShopperFee: false,
            shopperFee: 0,
            showDeliveryFee: false,
            deliveryFee: 0,
          }}
        />
        <CheckoutButton
          key="submit-order"
          dataIn={{ label: 'Pay Now' }}
          dataOut={() => {}}
        />
      </CheckoutGAppFlow>
    </React.Fragment>
  );
};

const CheckoutButton = (props: any) => {
  return (
    <Button
      mode={props?.dataIn?.mode || 'contained'}
      disabled={props?.dataIn?.disabled || props?.dataIn?.loading}
      onPress={props?.dataOut}
    >
      {props?.dataIn?.loading ? 'Loading...' : props?.dataIn?.label}
    </Button>
  );
};

const SelectPaymentMethod = ({ dataIn, dataOut }: any) => {
  return (
    <React.Fragment>
      <Text>Select Payment method</Text>
      <CheckoutButton
        dataIn={{
          label: dataIn.label,
          mode: 'outlined',
        }}
        dataOut={dataOut}
      />
    </React.Fragment>
  );
};

export default Checkout;

License

MIT