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!).
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 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 insettings.json
.type
: the type of charge (currently onlystripe
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.
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"
},
}
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.
<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 yoursettings.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 thecharge
as result argument).fragment
: a GraphQL fragment specifying the fields expected in return after the charge.fragmentName
: a registeredGraphQL fragment name.
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.
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.