Documentation You are here: start » v » 2.0 » fighting-fraud

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
v:2.0:fighting-fraud [2017/07/20 12:22] – [Example Endpoint] adamv:2.0:fighting-fraud [2021/06/09 08:47] (current) – [Extra Setup if you're using a Custom Subdomain] adam
Line 1: Line 1:
 ====== Fraud Prevention in FoxyCart ====== ====== Fraud Prevention in FoxyCart ======
 +
 +===== Foxy's Internal Abuse Prevention =====
 +
 +In addition to the options below, we have some systems in place to block more "obvious" fraud. We always recommend relying on your gateway's anti-fraud functionality, but you can rest easy knowing we'll prevent some of the more egregious abuse, before it even reaches your gateway.
  
 ===== minFraud in Foxy ===== ===== minFraud in Foxy =====
Line 5: Line 9:
  
 ==== What to do with it? ==== ==== What to do with it? ====
-You can enable minFraud in the "payment" page of your [[https://admin.foxycart.com/|FoxyCart admin]]. Simply set it to any number greater than 0 to enable it. Any transaction with a riskScore higher than the number you enter will be declined.+You can enable minFraud in the "payment" page of your [[https://admin.foxycart.com/|FoxyCart admin]]. The integration currently only works with those payment options that are available within the "Let customers pay with a Credit or Debit Card" option on the payment page. Simply set the minFraud score threshold setting within the "Anti-Fraud Integrations" area to any number greater than 0 to enable it. Any transaction with a riskScore higher than the number you enter will be declined.
  
 Though every store and customer base will have different riskScore averages, MaxMind's general recommendation is to //definitely// reject anything with a riskScore of 60 or higher, and to screen anything with a riskScore between 4-59. FoxyCart defaults to minFraud //off//, so **our recommendation is**: Though every store and customer base will have different riskScore averages, MaxMind's general recommendation is to //definitely// reject anything with a riskScore of 60 or higher, and to screen anything with a riskScore between 4-59. FoxyCart defaults to minFraud //off//, so **our recommendation is**:
Line 37: Line 41:
 Foxy's [[https://www.google.com/recaptcha/intro/|reCAPTCHA]] integration can be useful to preventing bots from aggressively scripting and pushing through transactions in an automated way. Note that reCAPTCHA is specifically to ensure that a //human// must be behind the request, but it has no opinion on whether that human is an honest person or a fraudster. Foxy's [[https://www.google.com/recaptcha/intro/|reCAPTCHA]] integration can be useful to preventing bots from aggressively scripting and pushing through transactions in an automated way. Note that reCAPTCHA is specifically to ensure that a //human// must be behind the request, but it has no opinion on whether that human is an honest person or a fraudster.
  
-Foxy defaults to reCAPTCHA being offbut has 2 different options:+The setting is shown within the “Anti-Fraud Integrations” sectiondisplayed within the “Let customers pay with a Credit or Debit Card” payment option when enabled.
  
-  - **Enabled, Always.** As it sounds, this will include reCAPTCHA on every checkout. +<WRAP center round info 95%> 
-  - **Enabled, Automatically as Needed.** This will require reCAPTCHA for checkouts loaded by IP addresses that have triggered multiple errors in preceding window of time. We attempt to set this so it would //very// rarely be shown to a legitimate customer, but would effectively make bot-based bulk fraud impossible. We don't publicize the exact thresholds, and may change them as needed. +If you're using a payment option which is configured outside of the "Let customers pay with a Credit or Debit Card" option, to enable Google reCAPTCHA you'll need to currently enable the "Let customers pay with a Credit or Debit Cardoption, set your reCAPTCHA setting as neededdisable the "Let customers pay with a Credit or Debit Cardoption again and saveThis will be corrected soon so this extra step isn't needed.
- +
-Note that reCAPTCHA isn't required for API-based or [[v:2.0:unified_order_entry|UOE]]-based transactions. +
- +
-===== Pre-Checkout Hooks ===== +
- +
-The Pre-Checkout Hook functionality allows for stores to apply custom validations for transactions prior to the request being set to the chosen payment method. A payload containing information about the current transaction is sent to the endpoint configured for this functionality, allowing the endpoint to respond to either approve or reject the transaction. If approved, the transaction will be sent on to the gateway to process, or if rejected the customer will be sent back to the checkout with a custom error message. +
- +
-Common use cases for the pre-checkout hook include: +
- +
-  * Final inventory checks for low-stock or one-of-a-kind products +
-  * Custom validations to ensure that certain product configurations are present +
-  * Integrations with custom validation or fraud-check services +
- +
-==== Enabling the Pre-Checkout Hook ==== +
- +
-To enable the pre-checkout hook, head to the "payment" setting page in your store's FoxyCart administration, ensuring that you've selected the [[v:2.0:payment_sets|payment set]] you're wanting to enable the hook for. Within the "Anti-Fraud Integrationssectioncheck the checkbox to "enable custom pre-checkout hook" and complete the settings below. +
- +
-  ; pre-checkout hook url +
-  : The URL for the endpoint script, which needs to be HTTPS, which will receive the JSON payload. +
-  ; failure handling +
-  : If your endpoint script fails to load or respond correctly, use this setting to set whether the transaction should be automatically approved or rejected. If set to reject, a generic error message will be returned, which you can edit the error from the "language" section of your store's administration - look for the "error precheckout hook" language string within the "checkout" group. +
- +
- +
-==== Handling the request ==== +
- +
-When the customer attempts to complete their purchase, after the Google reCAPTCHA is validated (if active), a POST request is sent off to your custom post-checkout hook endpoint with a JSON payload representing the current cart. It follows the same structure as our [[https://api.foxycart.com|Hypermedia API]]as the majority of the data comes from there. +
- +
-The following is an example of the JSON payload, showing two products (with one having live rates) and having coupon added. +
- +
-<code javascript> +
-+
-    "_links":+
-    }, +
-    "_embedded":+
-        "fx:items":+
-            { +
-                "_links":+
-                }, +
-                "_embedded":+
-                    "fx:item_options":+
-                        { +
-                            "_links":+
-                            }, +
-                            "name": "size", +
-                            "value": "medium", +
-                            "price_mod": 0, +
-                            "weight_mod": 0, +
-                            "date_created": null, +
-                            "date_modified": null +
-                        }, +
-                        { +
-                            "_links":+
-                            }, +
-                            "name": "color", +
-                            "value": "red", +
-                            "price_mod": 0, +
-                            "weight_mod": 0, +
-                            "date_created": null, +
-                            "date_modified": null +
-                        } +
-                    ], +
-                    "fx:item_category":+
-                        "_links":+
-                        }, +
-                        "admin_email_template_uri": "", +
-                        "customer_email_template_uri": "", +
-                        "code": "DEFAULT", +
-                        "name": "Default for all products", +
-                        "item_delivery_type": "flat_rate", +
-                        "max_downloads_per_customer": 3, +
-                        "max_downloads_time_period": 24, +
-                        "default_weight": 0, +
-                        "default_weight_unit": "LBS", +
-                        "default_length_unit": "IN", +
-                        "shipping_flat_rate_type": "per_item", +
-                        "shipping_flat_rate": 5, +
-                        "handling_fee_type": "none", +
-                        "handling_fee": 0, +
-                        "handling_fee_minimum": 0, +
-                        "handling_fee_percentage": 0, +
-                        "customs_value": 0, +
-                        "discount_type": "", +
-                        "discount_name": "", +
-                        "discount_details": "", +
-                        "send_customer_email": false, +
-                        "send_admin_email": false, +
-                        "admin_email": "", +
-                        "date_created": null, +
-                        "date_modified": null +
-                    } +
-                }, +
-                "item_category_uri": "https://api.foxycart.com/item_categories/100", +
-                "name": "Example Product", +
-                "price": 15.99, +
-                "quantity": 1, +
-                "quantity_min": 0, +
-                "quantity_max": 0, +
-                "weight": 0, +
-                "code": "abc123", +
-                "parent_code": "", +
-                "discount_name": "", +
-                "discount_type": "", +
-                "discount_details": "", +
-                "subscription_frequency": "", +
-                "subscription_start_date": null, +
-                "subscription_next_transaction_date": null, +
-                "subscription_end_date": null, +
-                "is_future_line_item": false, +
-                "shipto": "Me", +
-                "url": "", +
-                "image": "", +
-                "length": 0, +
-                "width": 0, +
-                "height": 0, +
-                "expires": 0, +
-                "date_created": null, +
-                "date_modified": "2017-07-20T04:13:08-0700" +
-            }, +
-            { +
-                "_links":+
-                }, +
-                "_embedded":+
-                    "fx:item_category":+
-                        "_links":+
-                        }, +
-                        "admin_email_template_uri": "", +
-                        "customer_email_template_uri": "", +
-                        "code": "live", +
-                        "name": "Live Rates", +
-                        "item_delivery_type": "shipped", +
-                        "max_downloads_per_customer": 3, +
-                        "max_downloads_time_period": 24, +
-                        "default_weight": 5, +
-                        "default_weight_unit": "LBS", +
-                        "default_length_unit": "IN", +
-                        "shipping_flat_rate_type": "per_order", +
-                        "shipping_flat_rate": 1, +
-                        "handling_fee_type": "none", +
-                        "handling_fee": 0, +
-                        "handling_fee_minimum": 0, +
-                        "handling_fee_percentage": 0, +
-                        "customs_value": 0, +
-                        "discount_type": "", +
-                        "discount_name": "", +
-                        "discount_details": "", +
-                        "send_customer_email": false, +
-                        "send_admin_email": false, +
-                        "admin_email": "", +
-                        "date_created": null, +
-                        "date_modified": null +
-                    } +
-                }, +
-                "item_category_uri": "https://api.foxycart.com/item_categories/101", +
-                "name": "Another Product", +
-                "price": 20, +
-                "quantity": 1, +
-                "quantity_min": 0, +
-                "quantity_max": 0, +
-                "weight": 5, +
-                "code": "foo321", +
-                "parent_code": "", +
-                "discount_name": "", +
-                "discount_type": "", +
-                "discount_details": "", +
-                "subscription_frequency": "", +
-                "subscription_start_date": null, +
-                "subscription_next_transaction_date": null, +
-                "subscription_end_date": null, +
-                "is_future_line_item": false, +
-                "shipto": "Me", +
-                "url": "", +
-                "image": "", +
-                "length": 0, +
-                "width": 0, +
-                "height": 0, +
-                "expires": 0, +
-                "date_created": null, +
-                "date_modified": "2017-07-20T04:14:03-0700" +
-            } +
-        ], +
-        "fx:discounts":+
-            { +
-                "code": "coupon", +
-                "amount": -3.6, +
-                "name": "Default Discount", +
-                "display": "-$3.60", +
-                "is_taxable": false, +
-                "is_future_discount": false +
-            } +
-        ], +
-        "fx:custom_fields":+
-            { +
-                "name": "custom_note", +
-                "value": "Happy Birthday!", +
-                "is_hidden":+
-            }], +
-        "fx:shipment":+
-            "address_name": "", +
-            "first_name": "John", +
-            "last_name": "Smith", +
-            "company": "", +
-            "address1": "Main Street", +
-            "address2": "", +
-            "city": "Saint Paul", +
-            "region": "MN", +
-            "postal_code": "55116", +
-            "country": "US", +
-            "origin_region": "TX", +
-            "origin_postal_code": "77018", +
-            "origin_country": "US", +
-            "shipping_service_id": 0, +
-            "shipping_service_description": "", +
-            "is_residential": false, +
-            "item_count": 2, +
-            "total_weight": 5, +
-            "total_customs_value": 0, +
-            "total_handling_fee": 0, +
-            "total_flat_rate_shipping": 5, +
-            "total_item_price": 35.99, +
-            "total_tax": 3.24, +
-            "total_shipping": 0, +
-            "total_price": 39.23 +
-        }, +
-        "fx:customer":+
-            "id": "1512345", +
-            "first_name": "John", +
-            "last_name": "Smith", +
-            "email": "john@example.com", +
-            "tax_id": "", +
-            "is_anonymous": "0", +
-            "_embedded":+
-                "fx:payments":+
-                    { +
-                        "cc_type": "plastic", +
-                        "cc_number_masked": "xxxx xxxx xxxx 4242", +
-                        "cc_exp_month": "10", +
-                        "cc_exp_year": "2020", +
-                        "purchase_order": null +
-                    } +
-                ], +
-                "fx:default_billing_address":+
-                    "country": "US", +
-                    "region": "MN", +
-                    "city": "Saint Paul", +
-                    "postal_code": "55116", +
-                    "address1": "Main Street", +
-                    "address2": "", +
-                    "company": "", +
-                    "full_name": "John Smith", +
-                    "first_name": "John", +
-                    "last_name": "Smith", +
-                    "phone": "" +
-                } +
-            } +
-        } +
-    }, +
-    "customer_uri": "", +
-    "template_set_uri": "", +
-    "language": "", +
-    "locale_code": "en_US", +
-    "total_item_price": 35.99, +
-    "total_tax": 3.24, +
-    "total_shipping": 14.23, +
-    "total_future_shipping": 0, +
-    "total_order": 49.86, +
-    "date_created": null, +
-    "date_modified": "2017-07-20T04:12:25-0700" +
-+
-</code> +
- +
-=== Notes === +
- +
-  * The payload includes several _links arrays. These contain helpful URI's that could be used through the Hypermedia API if you're also making use of that. If not, these can be safely ignored. +
- +
-<WRAP center round important 90%> +
-FoxyCart expects a response from your endpoint within 20 seconds of the request being sent - so you will need to ensure that any logic that your endpoint undertakes is completed quickly. Remember that as this request happens after the customer clicks to complete their transaction, any extended delays with your endpoint will mean they will also be waiting longer for a response to their transaction.+
 </WRAP> </WRAP>
  
 +Foxy defaults to reCAPTCHA being ''Enabled, Automatically as Needed'', and is our recommended setting, but has 3 different options:
  
 +  - **Disabled**: turns off reCAPTCHA for your store
 +  - **Enabled, Always**: As it sounds, this will include reCAPTCHA on every checkout.
 +  - **Enabled, Automatically as Needed**: This will require reCAPTCHA only in specific situations when our systems have cause to believe your store needs extra protection. We do not reveal specific behavior here, but broadly: If we detect behavior that makes us think a bot (or botnet) is pushing transactions through without a real human behind it, we will enable reCAPTCHA either for specific IPs or for //all checkout attempts//. We attempt to set this so it would //very// rarely be shown to a legitimate customer, but would effectively make bot-based bulk fraud impossible.
  
 +Note that reCAPTCHA isn't required for API-based or [[.:unified_order_entry|UOE]]-based transactions.
  
-==== Sending response ==== +==== Extra Setup if you're using Custom Subdomain ====
- +
-In response, FoxyCart expects a JSON payload in the following format to be output on the page (prettified for display purposes): +
- +
-=== Approve === +
- +
-<code javascript> +
-+
-  "ok": true, +
-  "details": "" +
-+
-</code> +
- +
-=== Reject === +
- +
-<code javascript> +
-+
-  "ok": false, +
-  "details": "Sorry, we're all out of Example Products. Please remove that item from your cart and try again." +
-+
-</code> +
- +
-{{ :v:2.0:transaction_hook_error.png?nolink&600 |}} +
- +
-<WRAP center round important 90%> +
-Only a valid JSON object should be output to your custom endpoint. If you output other elements to the page that is not part of a valid JSON object, the hook will fail to process and the default handling will happen. +
-</WRAP>+
  
-==== Example Endpoint ====+If you're using a [[.:custom_domain|custom subdomain]], you'll need to do a few extra steps to get your own reCAPTCHA keys. We **STRONGLY RECOMMEND THIS**, as without it a botnet-based card-testing attack could cost hundreds or thousands of dollars in authorization fees.
  
-The following is an example PHP endpoint that could be used to handle the pre-checkout hook:+  - Go to the [[https://www.google.com/recaptcha/admin|Google reCAPTCHA]] admin area. (You'll need to login with your Google Account if you aren't already.) 
 +  - Enter a label that'll make it clear what these keys are for. Something like "My Example Store on FoxyCart", perhaps. This is just for your own use. 
 +  - Select the reCAPTCHA V2 option, and if given options, choose the "I'm not a robot" option 
 +  - Enter the domain that your FoxyCart account's checkout is using. For example, if your domain was ''secure.example.tld'', you'd enter ''example.tld''. Check the checkbox(es) to agree to Google's terms, and submit. 
 +  - It should be successful, and take you to a page with your Site Key and Secret Key. 
 +  - Copy those two keys into the "payment" page in your FoxyCart admin. (Make sure to put the Site Key in the right input field. Put the "Secret key" into the Foxy admin input for "secret key"
 +  Save the payment settings in the FoxyCart admin. 
 +  - Do some test transactions, if you'd like. (You can set the reCAPTCHA setting in your Foxy settings to "Enabled, Always", then load up your checkout. You should see the reCAPTCHA display on the checkout. Set it back to "Enabled, Automatically…" once you're done, if you'd prefer.)
  
-<code php> +===== FraudLabs Pro =====
-<?php +
-$rawPost file_get_contents('php://input'); +
-$cart_details json_decode($rawPost, true);+
  
-$response = array( +[[https://www.fraudlabspro.com/|FraudLabs Pro]] has built an anti-fraud integration for Foxy. There's a little setup involvedbut there are step-by-step instructions here: 
-    'ok' => true+  * [[https://wiki.foxycart.com/integration/fraudlabspro|FraudLabs Pro]]
-    'details' => '' +
-);+
  
-foreach($cart_details['_embedded']['fx:items'] as $item) { +===== Pre-Payment Webhook =====
-    if ($item['name'== 'Example Product') { +
-        $response['ok'false; +
-        $response['details'"Sorry, we're all out of Example Products. Please remove that item from your cart and try again."; +
-    } +
-}+
  
-header('Content-Type: application/json'); +The [[pre_payment_webhook|pre-payment web hook]] can be used for custom anti-fraud integrations.
-print json_encode($response); +
-</code>+
  
-==== Debugging Errors ====+    * [[https://wiki.foxycart.com/integration/fraudlabspro|FraudLabsPro]] has an integration available on our wiki. 
 +    * Some of our users have done custom [[https://www.signifyd.com/|Signifyd]] integrations using this functionality.
  
-If your pre-checkout hook endpoint fails to return a response, or returns a non-JSON response, a error will be added to your store's error log in the administration.  

Site Tools