-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LG-13706: Socure KYC Proofer #11093
LG-13706: Socure KYC Proofer #11093
Conversation
- Basic Proofer implementation for Socure KYC. - Request / Response classes, error handling, etc. changelog: Upcoming Features, Identity verification, Implement proofer for Socure KYC
def kyc_field_validations | ||
@field_validations ||= kyc('fieldValidations'). | ||
each_with_object({}) do |(field, valid), obj| | ||
obj[field.to_sym] = valid.round == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would we ever want this logic to change per-field? or are we set with anything above 0.5
is a pass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They will literally only send either 0.99
or 0.01
, I just figured .round
would avoid any weirdness with ==
and floating points
- Lint fixes - Move temporary consent timestamp back a little bit
VERIFIED_ATTRIBUTE_MAP = { | ||
address: %i[streetAddress city state zip].freeze, | ||
first_name: :firstName, | ||
last_name: :surName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is offtopic and unimportant, but is camelcase surName
our pattern or Socure's? My brain keeps either reading it as surfName
, or as two words (since camelCase) and wondering what a sur name is, like it's a foreign word. (I mean, it is, but who knows what a "south name" is?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is Socure's field naming. My thinking is that request/response class speak in terms of Socure's API and their naming, and the proofer class translates that to our conventions / case style
dob: input.dob&.to_date&.to_s, | ||
|
||
userConsent: true, | ||
consentTimestamp: 5.minutes.ago.iso8601, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems weird? Do they actually require a timestamp here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They do, and it needs to be recent enough or they will return an error
|
||
# > The country or jurisdiction from where the transaction originates, | ||
# > specified in ISO-2 country codes format | ||
countryOfOrigin: 'US', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idle curiosity: does the transaction "originate" from our servers, or the end user? I.e., we know CBP has a lot of users from Mexico; do we need to try to make this dynamic, or is it where we are?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where we are--on Socure's end they are using it for compliance stuff (like, "does GDPR apply to this transaction?")
# XXX: This should be set to the time the user submitted agreement, | ||
# which we are not currently tracking. The "5.minutes.ago" is | ||
# because Socure will reject times "in the future", so we avoid | ||
# our clocks being out of sync with theirs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unimportant but IMHO this comment makes more sense in the code. I wondered why it was set this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple of tickets in the epic to follow up on this:
stub_request(:post, 'https://example.org/api/3.0/EmailAuthScore'). | ||
to_return( | ||
status: 500, | ||
body: 'It works!', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
body: 'It works!', | |
body: 'It does not work!', |
(Only half-joking?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is my attempt at humor--Apache will display an "It works!" page by default, meaning that Apache is working, but this page is almost never what you actually want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ha! I am all for Apache jokes. I somehow missed this one, but I am 200 OK
with this now.
"it does the thing" is not good enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable to me. I was able to test it in the console successfully.
Definitely out of scope, if we ever even do it, but with @errors={:reason_codes=>["I919"]}
I can't help but think it'd be neat to map those to descriptions. But it's possible these are proprietary and/or there's not really a need to have them in the code? Just a musing for another time.
I think there is an API endpoint we can hit to get the descriptions, but they don't change too much over time, so we could possibly have a static mapping |
🎫 Ticket
Link to the relevant ticket:
LG-13706
🛠 Summary of changes
This PR adds an implementation of a Proofer for Socure's ID+ service (specifically the KYC module). It does not actually wire the proofer in anywhere--that will come in a future update.
📜 Testing Plan
You can test this manually!
DO NOT USE REAL PII
export SOCURE_IDPLUS_API_KEY=your-secret-api-key