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:07] – [Enabling the Pre-Checkout Hook] 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.
  
-  - **EnabledAlways.** As it soundsthis will include reCAPTCHA on every checkout. +<WRAP center round info 95%> 
-  - **EnabledAutomatically as Needed.** This will require reCAPTCHA for checkouts loaded by IP addresses that have triggered multiple errors in a 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'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" optionto enable Google reCAPTCHA you'll need to currently enable the "Let customers pay with a Credit or Debit Card" optionset your reCAPTCHA setting as neededdisable the "Let customers pay with a Credit or Debit Card" option again and save. This will be corrected soon so this extra step isn't needed. 
 +</WRAP>
  
-Note that reCAPTCHA isn't required for API-based or [[v:2.0:unified_order_entry|UOE]]-based transactions.+Foxy defaults to reCAPTCHA being ''Enabled, Automatically as Needed'', and is our recommended setting, but has 3 different options:
  
-===== Pre-Checkout Hooks =====+  **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.
  
-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 transactionIf 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.+Note that reCAPTCHA isn't required for API-based or [[.:unified_order_entry|UOE]]-based transactions.
  
-==== Enabling the Pre-Checkout Hook ====+==== Extra Setup if you're using a Custom Subdomain ====
  
-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 forWithin the "Anti-Fraud Integrations" sectioncheck the checkbox to "enable custom pre-checkout hook" and complete the settings below.+If you're using a [[.:custom_domain|custom subdomain]]you'll need to do a few extra steps to get your own reCAPTCHA keysWe **STRONGLY RECOMMEND THIS**as without it a botnet-based card-testing attack could cost hundreds or thousands of dollars in authorization fees.
  
-  ; pre-checkout hook url +  - 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.) 
-  : The URL for the endpoint script, which needs to be HTTPS, which will receive the JSON payload. +  - Enter label that'll make it clear what these keys are for. Something like "My Example Store on FoxyCart", perhapsThis is just for your own use
-  ; failure handling +  Select the reCAPTCHA V2 optionand if given optionschoose the "I'm not a robotoption 
-  : 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. +  Enter the domain that your FoxyCart account's checkout is usingFor exampleif your domain was ''secure.example.tld''you'd enter ''example.tld''. Check the checkbox(es) to agree to Google's termsand submit
- +  - It should be successfuland take you to a page with your Site Key and Secret Key
- +  - Copy those two keys into the "paymentpage in your FoxyCart admin(Make sure to put the Site Key in the right input fieldPut the "Secret keyinto the Foxy admin input for "secret key". 
-==== Handling the request ==== +  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 "EnabledAlways", then load up your checkoutYou should see the reCAPTCHA display on the checkoutSet it back to "EnabledAutomatically…" once you're done, if you'd prefer.)
-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 ratesand 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 thatIf not, these can be safely ignored. +
- +
- +
- +
-==== Sending a response ==== +
- +
-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 endpointIf you output other elements to the page that is not part of a valid JSON objectthe hook will fail to process and the default handling will happen. +
-</WRAP>+
  
-==== Example Endpoint ====+===== FraudLabs Pro =====
  
-The following is an example PHP endpoint that could be used to handle the pre-checkout hook:+[[https://www.fraudlabspro.com/|FraudLabs Pro]] has built an anti-fraud integration for Foxy. There's a little setup involved, but there are step-by-step instructions here: 
 +  * [[https://wiki.foxycart.com/integration/fraudlabspro|FraudLabs Pro]]
  
-<code php> +===== Pre-Payment Webhook =====
-<?php +
-$rawPost file_get_contents('php://input'); +
-$cart_details json_decode($rawPost, true);+
  
-$response = array( +The [[pre_payment_webhook|pre-payment web hook]] can be used for custom anti-fraud integrations.
-    'ok' => true, +
-    'details' => '' +
-);+
  
-foreach($cart_details['_embedded']['fx:items'as $item) { +    * [[https://wiki.foxycart.com/integration/fraudlabspro|FraudLabsPro]] has an integration available on our wiki. 
-    if ($item['name'] == 'Example Product') { +    * Some of our users have done custom [[https://www.signifyd.com/|Signifyd]] integrations using this functionality.
-        $response['ok'= false; +
-        $response['details'= "Sorry, we're all out of Example ProductsPlease remove that item from your cart and try again."; +
-    } +
-}+
  
-header('Content-Type: application/json'); 
-print json_encode($response); 
-</code> 

Site Tools