Updated

Shopify Plus Integration

Looking for a Shopify app that requires no code? Our Shopify app is coming soon!

CHANGE powers end-to-end donation processing and enables your customers to share their impact on social media. This guide will walk through how to integrate CHANGE into your Shopify Plus store.

For Shopify Plus, we recommend a serverless approach. In this guide, we’ll use AWS Lambda to submit a donation whenever a customer makes a purchase.

AWS Lambda

Nonprofit Lambda

Your shop may want to donate to different nonprofits based on product. This “product to nonprofit” mapping will be consumed both at time of donation, and when customers share social content. To avoid repeating this mapping in several locations, we suggest keeping this logic in its own service.

Create a Lambda with the following implementation:

const NONPROFITS = {
'SKU_shoes': 42,
'SKU_jacket': 123
};

exports.handler = async (event) => {
const {skus} = event.queryStringParameters;
return {
statusCode: 200,
nonprofit_ids: skus.map(sku => NONPROFITS[sku])
}
};

For the rest of this guide, we’ll assume this Lambda is deployed and available at https://my.lambda/nonprofits.

Donation Lambda

const crypto = require('crypto');

// Your webhook secret, available after creating a Shopify webhook.
SHOPIFY_SECRET = 'shhh';
// Your CHANGE secret, available from your CHANGE dashboard.
CHANGE_SECRET = 'shhh';

exports.handler = async (event) => {
const {body, headers} = event;

// Verify that the request is from Shopify.
verified = verifySource(body, headers['X-Shopify-Hmac-SHA256']);
if (!verified) {
return { statusCode: 401 };
}

const order = JSON.parse(body);
const skus = order.line_items.map(item => item.sku);

// The nonprofit is determined by the Nonprofit Lambda.
const nonprofitIDs = await fetch(`https://my.lambda/nonprofits?skus=${skus}`);

// Submit the donation information to CHANGE.
submitDonations(order.id, nonprofitIDs);

// Shopify expects a 200 response.
return { statusCode: 200 };
};

async function submitDonations(orderID, nonprofitIDs) {
await fetch('api.getchange.io/donations/create', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 1,
nonprofit_ids: nonprofitIDs,
order_id: order.id
})
});
}

function verifySource(data, hmacHeader) {
const hash = crypto.createHmac('sha256', SHOPIFY_SECRET)
.update(data)
.digest('base64');
return crypto.timingSafeEqual(hash, hmacHeader);
}

Donation funds processing: Whether API calls to /donations/create move donation funds or not depends on your business arrangement with CHANGE.

For the rest of this guide, we’ll assume this Lambda is deployed and available at https://my.lambda/donation.

Shopify Webhook

Add a Webhook for Order creation.

Go to your Shopify store admin, then Settings > Notifications > Scroll to the bottom of the page and click “Create webhook”.

In the popup, select Event: Order creation, and enter the URL of your Donation Lambda, https://my.lambda/donation. Click “Save webhook”.

Adding a shopify webhook

Shopify will then provide you with a shared secret:

Shopify webhook secret

Copy the shared secret, and paste it in the Donation Lambda as the SHOPIFY_SECRET:

// Your webhook secret, available after creating a Shopify webhook.
SHOPIFY_SECRET = 'your-shopify-secret';

Your webhook is ready to go!

Enable customer sharing

Coming soon

Our UI component for easy drop-in sharing is in the works. Check back soon!

Once your shop is submitting donations, you can enable customer sharing.

<change-social-content> UI Component

This drop-in component provides an interface for customers to choose and share your social media content.

change social content element

Add the component to your page via an HTML element and script tag. The displayed content is controlled by the order_id and nonprofit_id attributes.

<change-social-content
order_id="id_1234"
nonprofit_id="np_1234"
></change-social-content>
<script src="unpkg/v1"></script>

In Shopify, the order_id attribute is available via Liquid on the order confirmation page. It can be set like this:

<change-social-content
order_id={order.id}
></change-social-content>

Tease social content to increase conversion

If order_id is not provided, a preview of the social media content is still shown, but the customer will not be able to share it. This can be used to tease social media content before checkout is complete.

Nonprofit ID

The nonprofit_id depends on which product is being/has been purchased. We can look this up with the Donation Lambda service that we created in the previous section. Assuming the Lambda is available at https://my.lambda/nonprofits, the following script can be used to populate nonprofit_id:

<script>
const socialElement = document.querySelector('change-social-content');
fetch('https://my.lambda/nonprofits?sku=[{checkout.line_items | map: "sku"}]')
.then(JSON.parse)
.then(result => {
// If there are multiple line items, decide which one we should render
// social media content for.
socialElement.nonprofit_id = result[0];
});
</script>
Made with ❤ in San Francisco