@halo-media/spartan-express-checkout
TypeScript icon, indicating that this package has built-in type declarations

3.52.13 • Public • Published

Spartan Express Checkout

The main purpose of this library is to create an interactive widget for HTML5 based platforms.

Deploy

To update the widget instance at https://spartan-express-checkout.herokuapp.com/, log in to heroku, then:

git push heroku master

Stripe

Test cards

Stripe is integrated on the front end for payment processing. For testing purposes stripe provides the following https://stripe.com/docs/testing#cards.

Apply Pay / Google Pay

Apple pay and Google pay are integrated through stripe. For usage and testing, regardless of development enviroment or production, a https connection is REQUIRED. To produce this on local you will need a tool such as https://ngrok.com/.

For testing on local, you will need to use ngrok to port through to your localhost port through a https connection, and you can then test it there. This will also require you to run npm run server to start the express server enviroment that emulates the functionality on heroku.

Apple pay

Integrating Apple pay will require you to verify your domain with Apple. Instructions are available https://stripe.com/docs/stripe-js/elements/payment-request-button?html-or-react=react#verifying-your-domain-with-apple-pay.

A domain must be registered through your own stripe dashboard at the following https://dashboard.stripe.com/account/payments/apple_pay.

The domain association file is part of the package installed. If it is not available at /.well-known/apple-developer-merchantid-domain-association on your own site, please make sure it is hosted there.

Sezzle

To enable sezzle on the widget just set a Sezzle public api key on the configuration object. The widget will display the sezzle checkout option when the property is defined.

// Configuration object
{
  ...
  sezzlePublicKey: "sz_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  ...
}

Usage

Configuration

let configuration = {
  env: 'development', // Accepted values are: "production" and "development". (Defaults to: "development")
  enableStripePaymentElementsFlow: false, // This flag will enable the new Stripe Payment Elements flow
  allowPlatformSpecificPayment: false,
  api: 'API_URL',
  token: 'API_TOKEN',
  sezzlePublicKey: "sz_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  // Element represents the element it will render in to if modal is false
  widgetElement: {
    isModal: false, // True for modal experience (Needs to be opened via a click event), false for in page experience
    element: document.querySelector('#widget'),
  },
  account = {
    id: spartanAccount.id,
    firstName: spartanAccount.first_name,
    lastName: spartanAccount.last_name,
    emailAddress: spartanAccount.email,
    birthMonth: spartanAccount.birth_date.split('-')[1],
    birthDay: spartanAccount.birth_date.split('-')[2],
    birthYear: spartanAccount.birth_date.split('-')[0],
    gender: spartanAccount.gender,
    phoneNumber: spartanAccount.mobile_phone,
    tshirtShize: spartanAccount.tshirt_size,
    emergencyContactName: spartanAccount.emergency_contact_name,
    emergencyContactPhone: spartanAccount.emergency_contact_phone,
  },
  settings: {
    name: 'Spartan',
    logo: '',
  },
  gtm: {
    gtmId: 'GTM-T2PRR2V', // Spartan GTM Container, required
    auth: 'z_k7asSD5G-X1q_E_y-40g', // optional
    preview: 'env-122', // optional
    dataLayer: { // optional, anything in this object will be passed through to the dataLayer
      country: 'US',
      localCurrency: 'USD',
      transactionAffiliation: window.location.host
    }
  },
  intl: {
    currency: "MXN", // Values follow ISO 4217
    language: "en-US",
    translations: {} // key-value map
  },
  theme: {
    typography: {
      primary: 'Montserrat', // Fonts to Load
      primarySource: 'https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700;800;900&display=swap',
      secondary: 'Montserrat',
      secondarySource: ''
    }
  },
  // Url to assign tickets on completion
  assignUrl: 'https://ASSIGN_URL',
  // Show questions with tag "member"
  showMemberQuestion: true,
  // Call back when cart items are updated
  onCartItemChange: (item, quantity, eventName) => {
    console.log("onCartItemChange", `Quantity ${quantity}`, item);
  },
  // Call back once purchase is finished
  onConfirmation: () => {
  },
  // Call back to run once purchase is finished and user closes confirmation
  onConfirmationClose: () => {
    console.log(123)
  },
  // Call back to run when/if timer timesout
  onCheckoutTimeout: () => {
    console.log('timeout')
  },
  // Call back to run when user click on Ice Cream Social button, transactionId can be null
  onIceCreamSocialClick: (transactionId) => {
    console.log('Ice Cream Social', transactionId);
  },
  //Image path for background image in Ice Cream Social
  iceCreamSocialImagePath: 'https://IMAGE_PATH',
  //Show Ice Cream Social block or not
  showIceCreamSocial: true,
  //TS_org allows to know what rules apply to the price decomposition according to the regulations of each country
  TS_org: 'US',
  //Refund protect settings
  refundProtect: {
    //enable or disable refund protection in the widget
    enableRefundProtect: true,
    //establish location of refund protection source code.
    sourceURL: 'https://widget.protectgroup.com/dynamic-widget.js',
    //sourceURL: 'https://test.widget.protectgroup.com/dynamic-widget.js',

    // * In order to excude a question or ticket type from the order refund a exclusion tag is needed. It can be 
    //   done in the admin panel. By default that tag is 'not-refundable', but can be changed in the constants file.
  },
  //show GoFundraise block or not
  showGoFundraise: true
  //If showGoFundraise is true you need to add goFundraiseFundInfo. Use the exact funds names as shown below
  goFundraiseFundInfo: {
    americanCancerSociety: {
       beneficiaryAccountId: '13xxxxx',
      eventCampaingId: '1xxxx',
      waitForCompletion: true
    },
    other: {
      beneficiaryAccountId: '13xxxxx',
      eventCampaingId: '1xxxx',
      waitForCompletion: false
    }
  }
};

Callbacks

onCartItemChange

The callback triggers on each update on the amount of tickets to be purchased and every time a new product is added.

Item schema:

  available: boolean,
  fees: [{
    amount: number;
    name: string;
  }],
  ticketSummary: {
      id: string;
      name: string;
      eventId: string;
      description?: string;
      minimumAge: number;
      maximumAge: number;
      requiredGender: GenderType;
  },
  priceCents: number,
  stock: number,
  tags: string[],
  questions: [{
    defaultAnswer: string;
    defaultAnswerText: string;
    displayAsCheckbox: boolean;
    moreInfo: string;
    ordering: number;
    questionAnswers: [{
      addOnAmountCents: number;
      answer: string;
      id: string;
      ordering: number;
      oversell: boolean;
      quantityAvailable: number;
      questionId: string;
      showQuantity: boolean;
    }];
    questionId: string;
    questionName: string;
    questionText: string;
    questionType: {
      CHECKBOX = "checkbox",
      MULTIPLE = "multiple",
      TEXT = "text"
    },
    required: boolean;
    tags: string[];
  }],
  waveTimes?: [{
      waveTimeId: string;
      description: string;
      remainingQuantity: number;
      soldQuantity: number;
      startTimestamp: number;
      totalQuantity: number;
  }]
}

Quantity: selected quantity, number

Event name: Event name, related to the Item property, string.

onConfirmation

The callback is triggered after an order is submitted and a response is retrieved, confirming the payment.

onCartItemChange

The callback is triggered when cart items are updated.

onIceCreamSocialClick

The callback is triggered when the user click on Ice Cream Social button in confirmation page.

Setting the widget checkout tickets

In page

If isModal is set to false, collect the cart details via this format and load them in to the widget using setCheckoutTickets:

const checkoutTickets = [
  {
    ticketTypeId: '5054',
    eventId: '111',
    quantity: 1,
  },
  {
    ticketTypeId: '5058',
    eventId: '111',
    quantity: 3,
  },
];

spartanExpressWidget.setCheckoutTickets(checkoutTickets);

In Modal

If isModal is set to true:

TBD

User account

User account fields need to be loaded in to the widget configuration. This must be done on the user end, then attached to the configuration object, and passed in to the widget.

configuration.account = {
  firstName: account.first_name,
  lastName: account.last_name,
  emailAddress: account.email,
  birthMonth: account.birth_date.split('-')[1],
  birthDay: account.birth_date.split('-')[2],
  birthYear: account.birth_date.split('-')[0],
  gender: account.gender,
  phoneNumber: account.mobile_phone,
};

Script Tag

<script src="/dist/spartan-express-checkout.umd.js"></script>
<div id="widget"></div>
<script>
  const spartanExpressWidget = new SpartanExpressCheckout.Widget(configuration);
</script>

ES6 Import

import SpartanExpressCheckout from '@halo-media/spartan-express-checkout';

const spartanExpressWidget = new SpartanExpressCheckout.Widget(configuration);

spartanExpressWidget.setCheckoutTickets(checkoutTickets);

Readme

Keywords

none

Package Sidebar

Install

npm i @halo-media/spartan-express-checkout

Weekly Downloads

17

Version

3.52.13

License

ISC

Unpacked Size

5.58 MB

Total Files

5

Last publish

Collaborators

  • tspuller
  • halo-franklin
  • nataliacarrerahalo
  • rbacigalupo
  • demian.bara.halo
  • maxiathalo
  • davidkim9
  • juan.marchetto.halo