Import PayPal transactions as Shopify orders with Mechanic.

Mechanic is the one-tool-does-it-all automation app for Shopify. :)

Import PayPal transactions as Shopify orders

by Isaac Bowen (team@usemechanic.com)

Use this task when you want to record your external PayPal transactions as Shopify orders. Are you using PayPal subscriptions? Or receiving direct payments you'd like to record in Shopify? Use this task, or file a task request to have it modified for more purpose-specific uses. :) Again, this isn't for PayPal as a Shopify payment provider – it's for any time you might be using PayPal *outside* of your Shopify store.

Runs when user/paypal/ipn is triggered. Configuration includes send receipt, default memo, order requires shipping, mark as fulfilled, and send fulfillment receipt.

15-day free trial – unlimited tasks

Documentation

To get set up, follow our tutorial: Connecting PayPal to Mechanic.

Then, configure to taste. :) Mechanic will use the PayPal order memo as the sole line item in the orders that are created, falling back to your "Default memo" setting.

Out of the box, this task will only create orders for transactions in which payment successfully went through. To modify this task to perform extra functionality (like auto-tagging based on subscription events, for example), file a task request from your Mechanic home screen.

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Gurus, everybody.

That’s why we make it easy to configure automation without code, why we make it easy to tweak the underlying code once tasks are installed, and why we publish it all here for everyone to learn from.

Events
when user/paypal/ipn is triggered (user/paypal/ipn)
Options
send receipt (boolean), default memo, order requires shipping (boolean), mark as fulfilled (boolean), send fulfillment receipt (boolean)
Script
{% comment %}
  Hello, developer friend! :) Here's the PayPal IPN variable reference:

  https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNandPDTVariables

  ... and here's their IPN payload simulator:

  https://developer.paypal.com/developer/ipnSimulator/

  Their default payment_date value doesn't even meet *their* standard, so change it to
  something like "22:03:27 Sep 28, 2018 PDT" if you need to test that value. <3
{% endcomment %}

{% comment %}
  Decide if this IPN payload is something we should import as
  an actual order.
{% endcomment %}
{% assign import_order = false %}
{% assign allowed_txn_types = "cart,express_checkout,masspay,merch_pmt,mp_cancel,payout,pro_hosted,recurring_payment,send_money,subscr_payment,virtual_terminal,web_accept" | split: "," %}
{% if event.data.payment_status == "Completed" and allowed_txn_types contains event.data.txn_type %}
  {% assign import_order = true %}
{% endif %}

{% if event.preview or import_order %}
  {% comment %}
    PayPal's date format is non-standard: `HH:MM:SS Mmm DD, YYYY PDT`, per their docs.
    We reformat it here, to ensure that Liquid can parse it for Shopify-ready formatting.
  {% endcomment %}
  {% assign date_parts = event.data.payment_date | replace: ",", "" | split: " " %}
  {% capture sane_payment_date %}{{ date_parts[3] }} {{ date_parts[1] }} {{ date_parts[2] }} {{ date_parts[0] }} {{ date_parts[4] }}{% endcapture %}

  {
    "action": {
      "type": "shopify",
      "options": [
        "create",
        "order",
        {
          "email": {{ event.data.payer_email | json }},
          "send_receipt": {{ options.send_receipt__boolean | json }},
          "processed_at": {{ sane_payment_date | date: "%Y-%m-%dT%H:%M:%S.%L%z" | json }},
          "financial_status": "paid",
          "currency": {{ event.data.mc_currency | json }},
          "line_items": [
            {
              "title": {{ event.data.memo | default: options.default_memo | default: "(no memo given)" | json }},
              "price": {{ event.data.mc_gross | divided_by: 1.0 | json }},
              "requires_shipping": {{ options.order_requires_shipping__boolean | json }},
              "quantity": 1,
              "taxable": false
            }
          ],
          "fulfillment_status": {% if options.mark_as_fulfilled__boolean %}"fulfilled"{% else %}null{% endif %},
          "send_fulfillment_receipt": {{ options.send_fulfillment_receipt__boolean | json }},
          "transactions": [
            {
              "kind": "sale",
              "status": "success",
              "amount": {{ event.data.mc_gross | divided_by: 1.0 | json }}
            }
          ],
          "customer": {
            "id": {{ shop.customers[event.data.payer_email].id | json }}
          },
          "billing_address": {
            "first_name": {{ event.data.first_name | json }},
            "last_name": {{ event.data.last_name | json }},
            "address1": {{ event.data.address_street | json }},
            "city": {{ event.data.address_city | json }},
            "province": {{ event.data.address_state | json }},
            "country": {{ event.data.address_country | json }},
            "zip": {{ event.data.address_zip | json }}
          },
          "note_attributes": [
            {
              "name": "PayPal protection eligibility",
              "value": {{ event.data.protection_eligibility | json }}
            },
            {
              "name": "PayPal payer ID",
              "value": {{ event.data.payer_id | json }}
            },
            {
              "name": "PayPal transaction ID",
              "value": {{ event.data.txn_id | json }}
            },
            {
              "name": "PayPal receiver ID",
              "value": {{ event.data.receiver_id | json }}
            },
            {
              "name": "PayPal transaction type",
              "value": {{ event.data.txn_type | json }}
            }
          ]
        }
      ]
    }
  }
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.
Defaults
Default memo
Your PayPal payment