Best practises to verify card owner when adding credit card to user account - security

in our application we allow users to link card to their profile and use it later for payments inside our system. Recently we had a couple fraud attempts when users added stolen credit cards (so they knew all information about card, including CVV).
The only thing that we came up with is to make temporary payment of some small random amount so user can check bank transactions report and verify ownership by providing exact authorized amount.
Is there any other common proven ways to verify card ownership?

Yes, there are a couple of things you can do at the very least:
Validating the house number and postcode/zipcode provided to you with the result returned to your from your payment processor on the pre-auth (AVS - Address Verification Service).
3D secure verification (Mastercard SecureCode or Verified by Visa) - the user is redirected to their issuer's site (or one ran for them by e.g. Arcot) and has to enter a secret only known to them.
Validating a small random amount is also a good check to make, however this takes a few days whereas the above can be validated instantly.

Related

How to handle incomplete stripe connected account onboarding?

I am after the best practice for handling incomplete stripe connected account onboarding.
When onboarding goes smoothly, everything is simple. But there are fiddly edgecases everywhere, which results in a lot of permutations of values for account requirements
These include
current_deadline
currently_due
disabled_reason
errors
eventually_due
past_due
pending_verification
This creates a lot of complexity.
I need a simple way to:
figure out if the connected user needs to be notified of something (i.e. that they need to give more info), and
what to tell them.
My current strategy is to check if errors is empty, and if not, simply display them along with a link to manage the user's stripe account so they can address the errors.
But I'm worried this strategy will miss things (perhaps minor things that could be addressed before they become errors).
TL;DR I suspect most users will onboard without any problem, but for the few who do have issues, I want to ensure the app notifies them that they need to address them. What is the best way to do this? (using the information in requirements or other info)
When handling identity verification manually using the API, a simple way to check whether your connected user might need to be notified to provide more info is to look at the charges_enabled and payouts_enabled properties on the user's account object. If either of these two properties are false then you might need to reach out to the connected user for more information.
In cases where the connected user's charges and payouts are disabled, you would use the disabled_reason property on the requirements hash to learn the reason why charges and/or payouts are disabled. The possible disabled reasons are all documented here, but I'll list them out nonetheless:
action_required.requested_capabilities You need to request
capabilities for the connected account. For details, see Request and
unrequest capabilities.
requirements.past_due Additional verification
information is required to enable payout or charge capabilities on
this account.
requirements.pending_verification Stripe is currently
verifying information on the connected account.
rejected.fraud Account is rejected due to suspected fraud or illegal activity.
rejected.terms_of_service Account is rejected due to suspected terms
of service violations.
rejected.listed Account is rejected because
it's on a third-party prohibited persons or companies list (such as
financial services provider or government).
rejected.other Account is rejected for another reason.
listed Account might be on a prohibited persons or companies list (Stripe will investigate and either reject or reinstate the account appropriately).
under_review Account is under review by Stripe.
other Account isn't rejected but is disabled for another reason while being reviewed.
Using the disabled_reason, you can assess whether the user needs to be notified with a request for more information (i.e., requirements.past_due), whether they need to be notified for another reason (e.g., rejected.listed), or whether you need to make programmatic changes to the user's Stripe account (e.g., action_required.requested_capabilities).

Prevent multiple stripe trials by card details

We are looking to offer a free trial of our product with payments powered by Stripe Subscriptions.
However, what I'm not sure about is whether it is possible to prevent a user from having multiple emails by limiting it to one trial by card, similar to how sites like Netflix operate.
You can definitely do this though you have to build the logic yourself. The idea is that you can detect duplicate cards and automatically block ones you've seen before if they try to access the trial.
Stripe returns the fingerprint property on Cards. That property is a unique identifier for a given card number in your account.
This means that if I sign up today with my card and then I come back tomorrow with the same card under a different email address you'd see the same exact fingerprint on both tokens or card objects.
The idea then would be to keep track of all the card fingerprints you see in your database to detect a returning customer. Whenever a customer adds a new card you'd first look if you've seen that card fingerprint before in your database and decide to create the customer or return an error based on this.

How to collect members' bank info?

Say I have a company where I want to make direct deposits to members' bank account. I understand that's it a really bad idea to ask them their information on the site and store it in the database.
But what If i ask our members to email us their bank info for direct deposits? I would then simply take their info and put it in excel sheet instead of storing it in the server(and delete the original email). That would be my reference point to sending the members direct deposits using my bank account. Is that legally allowed? If not, what would be another method to request a member's bank account info to make direct deposits?
Collecting banking account information has significant security implications and doing via email is not kosher. But there are alternatives.
The simplest alternative is using interbank service like Zelle where you can send money to your members' bank accounts using just their email accounts (the one associated with their bank login). We pay our smaller vendors this way and most get paid immediately without any transaction fees. But this may not work for members who use smaller banks outside the network (e.g credit unions) and the service does not have sophisticated tracking or linking to invoices.
If you have international members or need a more scalable/programmatic/self-serve solution, you can consider using a payment gateway provider like paypal/braintree or stripe-connect. Stripe is especially easy to integrate with a website and instead of you collecting and maintaining banking information for your members, stripe does on your behalf. Companies like Lyft use this to pay their drivers. It scales and works in almost all major international locations. Downside is there are per transaction fees which get steep if you want instant payments.

How to charge credit card AND set up automated recurring billing in one step with Authorize.Net

I’m integrating authorize.net into my web application. I’ve used the direct post method (DPM)to charge the account initially. However, for each transaction I also need to set up automated reoccurring billing. How would I go about doing this without asking for the information again, particularly when after DPM posts the initial transaction, the credit card data is no longer available?
I also would like to get the status of each reoccurring transaction so it can be confirmed and followed up on if necessary.
You can't do that with DPM as it takes the user's credit card information off of your website so you don't have access to it. If you want to make an initial payment and then use ARB to create a subscription you need to use AIM with ARB.
You need to use the ARB interface in order to do recurring transactions but there are a lot of problems with it, like lack of support (send an email and wait a couple of weeks for a non-helpful response for example) and weak documentation.
Documentation for SOAP interface for Authorize.net ARB:
http://www.authorize.net/support/ARB_SOAP_guide.pdf
And for the XMl interface:
http://www.authorize.net/support/ARB_guide.pdf
ARB programming documentation:
http://developer.authorize.net/api/arb/
I just switched off of Authorize.net to USAEPAY. Here are some reasons why:
1. When you use Authorize.net ARB, your customer comes on the site to sign up, and you send the ARB request to create the subscription and you get back a success code so you give the user the subscription. Then later that night they actually try to collect the first payment and a lot of times this fails, so you get a spreadsheet emailed to you the next day about the problem. This is terrible because now you lost the opportunity to say to the customer at sign up time that the card is declined. Goodbye sale!
2. I don't know if they added this recently but they didn't have a way to verify if a customer's credit card is still valid. Imagine 3 months into a subscription the card is over the limit, or cancelled, or expired etc. You don't know so how do you prompt the customer to put in a new card? You just stop getting paid, unless you want to manually open these spreadsheets and start emailing customers. YUCK.
USAEPAY works much better, the API is easier, its much better documented and you get email responses in 1-2 days and its less expensive. For example, you can query USAEPAY to get a list of successful payments, and verify that you shouldn't deactivate the account for non-payment:
http://wiki.usaepay.com/developer/soap-1.4/methods/getcustomerreport
Before you go too far with AuthNet I highly encourage you to save yourself a lot of pain and contact FranchisePaymentNetwork (FPN) to get set up with USAEpay.
They can even POST BACK to your website to let you know if a transaction is successful or not for recurring billing transactions and you can query it to verify that customer payments are getting collected so you know if you should expire an account or not.
I am not affiliated with USAEpay or Franchise Payment Network except as a satisfied paying customer / consumer of their services.

Preventing fake accounts

I'm working on a simple web service that allows users to sign up for free and upload a small amount of data. I can easily establish a quota for each user, but malicious users could create fake accounts to upload as much data as they like in a denial-of-service attack.
Obviously, there's no perfect defense against this type of attack, but what can we do to mitigate this problem?
Tie it to a more-or-less unique identifier (phone number, bank account number, facebook/google/etc account) or to a finite resource (such as time, by using a captcha).
use a captcha on account creation to ensure that it's a
human and not an automated process.
require a valid email address and require that they click a link in their email to validate that that's their email address and continue the registration process. This cuts down on their ability to create many throwaway accounts because you can limit them to only having one account per email address and they have to then create a new email address for each account they want to create.
When the user signs up, the user supplies a valid email. Most accounts are not enabled until a response has been received, usually by clicking a link in the body of that email. When that click-through is received, you should be able to grab an IP address. That should help you curtail an abundance of casual DOS attacks.
Consider Phone Number Verification
Requiring phone number for account creation is the best approach I've come across; Creating a new email or cycling an IP address is pretty trivial, but genuine sms phone numbers cost money to activate & grant your service the ability to restrict access by country-code.
An important caveat: Virtual phone numbers (like google-voice), temporary-phone number services, & burner phones can make sms-verification ineffective at preventing duplicate user accounts. Depending on your use case, it might be worthwhile to use a service, like Vonage's Number Insight api, that lets you identify those types of numbers.
Authillo is a passwordless authentication provider that prevents duplicate/fake accounts by leveraging sms verification, liveness detection, & facial recognition. Depending on how critical it is that you prevent fake accounts on your service, their base plan might be what you're looking for.
Just log the IPs and assume the same user if the IP does not change within a time interval. This is bad, because it would prevent multiple users in the same house (same IP) but it is a good start.

Resources