forked from lightward/mechanic-tasks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpartially-auto-capture-payments-as-orders-are-fulfilled.json
21 lines (21 loc) · 7.08 KB
/
partially-auto-capture-payments-as-orders-are-fulfilled.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"docs": "Running when an order is updated, this task captures payment in proportion to the order value that has been fulfilled. For example, for an order with a subtotal of $10 and a total of $15 with shipping/taxes/discounts, this task will capture $7.50 when $5 of the order's value has been fulfilled.\n\nThis task only works with payment gateways that support multiple captures against an authorization, which includes Shopify Payments. However, this task will not process orders that use multiple payment gateways *on the same order*.\n\nNote: To find the payment gateway names, you will need to check the **payment_gateway_names** field on any order that uses the gateway(s) you wish to configure in this task. One method of doing this is to add **.json** to the end of the order admin page address, and searching for *payment_gateway_names* (e.g. \"https[]()://admin.shopify.com/store/my-shop/orders/1234567890.json\").",
"halt_action_run_sequence_on_error": false,
"name": "Partially auto-capture payments as orders are fulfilled",
"online_store_javascript": null,
"options": {
"payment_gateway_names__array_required": null
},
"order_status_javascript": null,
"perform_action_runs_in_sequence": false,
"script": "{% assign payment_gateway_names = options.payment_gateway_names__array_required %}\n\n{% if event.preview %}\n {% assign order = hash %}\n {% assign order[\"admin_graphql_api_id\"] = \"gid://shopify/Order/1234567890\" %}\n {% assign order[\"financial_status\"] = \"partially_paid\" %}\n{% endif %}\n\n{% if order.financial_status != \"authorized\" and order.financial_status != \"partially_paid\" %}\n {% log \"Order is not either authorized or partially_paid.\" %}\n\n{% else %}\n {% capture query %}\n query {\n order(id: {{ order.admin_graphql_api_id | json }}) {\n id\n paymentGatewayNames\n transactions(capturable: true) {\n id\n amountSet {\n presentmentMoney {\n amount\n currencyCode\n }\n }\n }\n totalPriceSet {\n presentmentMoney {\n amount\n }\n }\n subtotalPriceSet {\n presentmentMoney {\n amount\n }\n }\n totalCapturableSet {\n presentmentMoney {\n amount\n }\n }\n fulfillments {\n name\n fulfillmentLineItems(first: 250) {\n pageInfo {\n hasNextPage\n }\n nodes {\n discountedTotalSet {\n presentmentMoney {\n amount\n }\n }\n }\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = query | shopify %}\n\n {% if event.preview %}\n {% capture result_json %}\n {\n \"data\": {\n \"order\": {\n \"paymentGatewayNames\": [\n {{ payment_gateway_names.first | json }}\n ],\n \"transactions\": [\n {\n \"id\": \"gid://shopify/OrderTransaction/1234567890\",\n \"amountSet\": {\n \"presentmentMoney\": {\n \"amount\": \"16.99\",\n \"currencyCode\": \"USD\"\n }\n }\n }\n ],\n \"totalPriceSet\": {\n \"presentmentMoney\": {\n \"amount\": \"16.99\"\n }\n },\n \"subtotalPriceSet\": {\n \"presentmentMoney\": {\n \"amount\": \"10.0\"\n }\n },\n \"totalCapturableSet\": {\n \"presentmentMoney\": {\n \"amount\": \"16.54\"\n }\n },\n \"fulfillments\": [\n {\n \"name\": \"#1234-F1\",\n \"fulfillmentLineItems\": {\n \"nodes\": [\n {\n \"discountedTotalSet\": {\n \"presentmentMoney\": {\n \"amount\": \"5.0\"\n }\n }\n }\n ]\n }\n }\n ]\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n {% endif %}\n\n {% assign order = result.data.order %}\n\n {% unless order.paymentGatewayNames.size == 1 and payment_gateway_names contains order.paymentGatewayNames.first %}\n {% log\n message: \"This order did not use one of the configured gateways or there are multiple gateways on the order; skipping.\",\n configured_payment_gateway_names: payment_gateway_names,\n order: order\n %}\n {% break %}\n {% endunless %}\n\n {% assign total = order.totalPriceSet.presentmentMoney.amount | times: 1.0 %}\n {% assign total_captured = total | minus: order.totalCapturableSet.presentmentMoney.amount %}\n {% assign subtotal = order.subtotalPriceSet.presentmentMoney.amount | times: 1.0 %}\n {% assign subtotal_fulfilled = 0.0 %}\n\n {% for fulfillment in order.fulfillments %}\n {% if fulfillment.fulfillmentLineItems.pageInfo.hasNextPage %}\n {% error \"This order has a fulfillment with more than 250 line items in it. This is not supported by this task.\" %}\n {% break %}\n {% endif %}\n\n {% for fulfillment_line_item in fulfillment.fulfillmentLineItems.nodes %}\n {% assign subtotal_fulfilled = subtotal_fulfilled | plus: fulfillment_line_item.discountedTotalSet.presentmentMoney.amount %}\n {% endfor %}\n {% endfor %}\n\n {% assign desired_total_captured = subtotal_fulfilled | divided_by: subtotal | times: total %}\n {% assign amount_to_capture = desired_total_captured | minus: total_captured | times: 100 | round | divided_by: 100.0 %}\n {% assign parent_transaction = order.transactions.first %}\n\n {% log\n total: total,\n total_captured: total_captured,\n subtotal: subtotal,\n subtotal_fulfilled: subtotal_fulfilled,\n desired_total_captured: desired_total_captured,\n amount_to_capture: amount_to_capture,\n parent_transaction: parent_transaction\n %}\n\n {% if order.capturable == false %}\n {% log \"This order is not capturable.\" %}\n\n {% elsif amount_to_capture == 0 %}\n {% log \"Nothing to capture at this time.\" %}\n\n {% else %}\n {% action \"shopify\" %}\n mutation {\n orderCapture(\n input: {\n id: {{ order.id | json }}\n parentTransactionId: {{ parent_transaction.id | json }}\n amount: {{ amount_to_capture | append: \"\" | json }}\n currency: {{ parent_transaction.amountSet.presentmentMoney.currencyCode }}\n }\n ) {\n transaction {\n id\n status\n }\n userErrors {\n field\n message\n }\n }\n }\n {% endaction %}\n {% endif %}\n{% endif %}\n",
"subscriptions": [
"shopify/orders/updated"
],
"subscriptions_template": "shopify/orders/updated",
"tags": [
"Fulfillment",
"Orders",
"Payment"
]
}