Skip to content

Instantly share code, notes, and snippets.

@SachaG
Last active June 8, 2017 15:15
Show Gist options
  • Save SachaG/91c16d2852eb33b14ddfb91148ef409a to your computer and use it in GitHub Desktop.
Save SachaG/91c16d2852eb33b14ddfb91148ef409a to your computer and use it in GitHub Desktop.

Vulcan Charge

This package helps you process charges with Vulcan. It currently only supports Stripe, but other payment processors may be supported in the future (PRs welcome!).

Overview

This package does the following things:

  • Provide a button that triggers the Stripe Checkout form.
  • Once the form is submitted, trigger a GraphQL mutation that will perform the charge.
  • The mutation then returns a document associated with the charge.

Charges

Charges are stored in the database with the following fields:

  • _id: the charge's id.
  • createdAt: the charge's timestamp.
  • userId: the Vulcan _id of the user performing the purchase.
  • tokenId: the charge token's id.
  • productKey: the key corresponding to the product being purchased, as defined in settings.json.
  • type: the type of charge (currently only stripe is supported).
  • test: whether the operation is a test or not.
  • data: a JSON object containing all charge data generated by the payment processor.
  • ip: the IP address of the client performing the purchase.

Settings

Stripe requires the following public settings in your settings.json.

  • public.stripe.publishableKey: your publishable Stripe key.
  • public.stripe.products: an array of products.

As well as the following private setting (can be stored in the setting's root or on private):

  • stripe.secretKey: your Stripe secret key.
{
  "public": {
    "stripe": {
      "publishableKey": "pk_test_K0rkFDrT0jj4NqG5Dumr3RaU",
      "products": {
        "sponsorship": {
          "name": "Sidebar Sponsorship",
          "amount": 95000,
          "currency": "USD",
          "description": "Sponsor Sidebar for a week."
        },
        "jobPosting": {
          "name": "Sidebar Job Posting",
          "amount": 25000,
          "currency": "USD",
          "description": "Post a job offer on Sidebar."
        }
      }
    }
  },
  "stripe": {
    "secretKey": "sk_test_sfdhj34jdsfxhjs234sd0K"
  },
}

Products

A product is a type of purchase a user can make. It has a name, amount, currency, and description.

By defining products in your settings file, you can access them both on the front-end to configure Stripe Checkout, and in the back-end to perform the actual charge.

Each product should have a unique product key (sponsorship, jobPosting, etc.) used to identify it.

Checkout Component

<Components.Checkout 
    productKey="jobPosting"
    associatedCollection={Jobs}
    associatedId={job._id}
    callback={setToPaid}
    button={<Button className="buy-job-button" bsStyle="primary">Complete Payment</Button>}
  />
  • productKey: The key of the product to buy, as defined in your settings.json file.
  • button: The button that triggers the Stripe Checkout overlay.
  • associatedCollection: the associated collection.
  • associatedId: the associated _id.
  • callback: a callback function that runs once the charge is successful (takes the charge as result argument).
  • fragment: a GraphQL fragment specifying the fields expected in return after the charge.
  • fragmentName: a registeredGraphQL fragment name.

Associating a Collection Document

The Vulcan Charge package requires associating a document with a purchase, typically the item being paid for. For example, maybe you want people to buy access to a file hosted on your servers, and give them download access once the transaction is complete.

The associatedCollection and associatedId props give you an easy way to implement this by automatically setting a chargeId field on the document once the charge succeeds.

For example, if you pass associatedCollection={Jobs} and associatedId="foo123" to the Checkout component, the resulting charge's _id will automatically be added to a chargeIds array on job foo123.

The createChargeMutation GraphQL mutation will then return that job according to the fragment property specified.

Post-Charge Updates

The best way to update a document based on a successful charge is by using a callback. For example here's how you would change the status field of a job posting when a charge's _id has successfully been added to the job's chargeIds array:

import { addCallback } from 'meteor/vulcan:core';

function setApprovedWhenPaid (modifier, document, currentUser) {
  if (modifier.$set.chargeIds) {
    modifier.$set.status = 2;
  }
  return modifier;
}

addCallback('jobs.edit.sync', setApprovedWhenPaid);

Because the callback is added in a sync manner, the final document returned by the createChargeMutation mutation will include the new status value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment