We recently released a few improvements to signing notifications and error handling. If you are using e-signatures via the API or have the signing UI embedded in your app, this is for you! These new features will help you provide your users with a better experience both after signing, and when they experience an error. This post will take you through the improvements and how you can take advantage of them in your app.
TL;DR, what changed?
- The query params passed to a signer's
redirectURL
have been updated:- There is a new
errorType
query param and related error information passed in the event of an error - There is an additional
action
query param sent on a successful signing event
- There is a new
- Updates to
react-signature-frame
andreact-signature-frame
(versions1.6.0
) have been released including anonError
callback and more information from theonFinishSigning
callback. - For customers embedding the signing UI in their app, there is more information passed to the parent frame via
postMessage
, including error information and signer information - Information about a signer's signing tokens is now exposed through the GraphQL endpoint. You can fetch expiry timestamp, etc.
- There is more documentation on how to recover from token expired errors
New redirect URL parameters
If you're specifying a redirectURL
on your signers, you will notice a new query parameter:
action
: All calls to yourredirectURL
will now include anaction
query parameter. For now, the value will be eithersignerComplete
(success!) orsignerError
(error)
In the event of an error, there will be a couple more query parameters:
errorType
: The error that occurred. The value will be one oftokenExpired
,tokenInvalid
, ornotFound
. OnlytokenExpired
is a recoverable errorerror
: The title of the error that occurredmessage
: The message of the error that occurred
An example of a successful callback:
GET https://yoursite.com/signer-complete
?action=signerComplete # New!
&signerStatus=completed
&signerEid=SI8xMh51WBR9dyGILDoL
&nextSignerEid=s1AFrmQeuj3qMchKmhL2
&documentGroupStatus=completed // completed || partial || sent
&documentGroupEid=GqqU9OKLhmnGBeCusRRa
&etchPacketEid=rmmhL2s1AQeuj3qhKFMc
An example of an error callback
GET https://yoursite.com/signer-complete
?action=signerError
&errorType=tokenExpired # tokenExpired || tokenInvalid || notFound
&error=Token+Expired
&message=Error+specific+message
&signerStatus=sent
&signerEid=SI8xMh51WBR9dyGILDoL
&documentGroupStatus=sent
&documentGroupEid=GqqU9OKLhmnGBeCusRRa
&etchPacketEid=rmmhL2s1AQeuj3qhKFMc
See the redirectURL
docs for full details.
Updates to react-ui packages
Our react components AnvilSignatureFrame
and AnvilSignatureModal
have a couple of brand new callbacks as of version 1.6.0
: onFinishSigning
and onError
. You can take action on these instead of showing your own page within the iframe
on redirect. The data mirrors that of the query params sent to a signer's redirectURL
. These callbacks will be called from the iframe
to the parent frame before the browser is redirected to the redirectURL
.
Note that the previous onFinish
callback is deprecated in favor of these new callbacks. If you are using the previous onFinish
callback, please upgrade to 1.6.0
and use the new callbacks!
<ReactSignatureFrame // or ReactSignatureModal
onFinishSigning={(successInfo) => {
// `successInfo` will be an object with the following shape:
// {
// action: 'signerComplete',
// signerStatus: 'completed',
// signerEid: 'SI8xMh51WBR9dyGILDoL',
// nextSignerEid: 's1AFrmQeuj3qMchKmhL2',
// documentGroupStatus: 'completed',
// documentGroupEid: 'GqqU9OKLhmnGBeCusRRa',
// etchPacketEid: 'rmmhL2s1AQeuj3qhKFMc',
// }
}}
onError={(errorInfo) => {
// `errorInfo` will be an object with the following shape:
// {
// action: 'signerError',
// errorType: 'tokenExpired',
// error: 'Token Expired',
// message: 'Error specific message',
// signerStatus: 'sent',
// signerEid: 'SI8xMh51WBR9dyGILDoL',
// documentGroupStatus: 'sent',
// documentGroupEid: 'GqqU9OKLhmnGBeCusRRa',
// etchPacketEid: 'rmmhL2s1AQeuj3qhKFMc',
// }
}}
/>
Updates to the parent frame callback
When the e-signature page is embedded in an iframe
and the user finishes signing or experiences an error, the signing page will send a message to the parent frame via postMessage
. This was the case previously, but now it will be called with the URL including all query parameters mentioned in the redirectURL
. Our react components use this handler to implement its callbacks.
Here is how to handle the notification from the parent frame:
window.addEventListener('message', ({ origin, data }) => {
if (origin !== 'https://app.useanvil.com') return
if (data && typeof data === 'string') {
// You will receive the redirectURL when the signing process is complete or
// when there is an error. e.g.
//
// https://app.useanvil.com/finishpage?action=...&...
//
// You do not need to redirect to this URL, the iframe will make the
// redirect.
if (data.indexOf('action=signerComplete') > -1) {
// A signer has finished signing
} else if (data.indexOf('action=signerError') > -1) {
// A signer has experienced an error
}
}
})
See the embedding docs for more information.
Signer token metadata
You may want to know token expiry dates to preemptively handle upcoming token expirations. You can fetch validity and expiration information via the new signerTokens
resolver on the Signer
GraphQL object. The most effective way to fetch this information is through an etchPacket
:
query etchPacket($eid: String!) {
etchPacket(eid: $eid) {
eid
status
documentGroup {
signers {
signerTokens {
eid
type
validUntil
valid
invalidatedAt
hasSigned
signedAt
}
}
}
}
}
For more information see the fetching token metadata section in the docs.
Recovering from token expired errors
Now you know how to get notified when errors happen by way of a redirect or a callback, but how should you recover from them?
The most important error you should be handling is tokenExpired
. This will happen when a user visits a signing link with an expired token, or a token that once was valid, but is no longer valid. It doesn't happen very often, but when it does, an error page isn't the best experience for your users.
The crux of recovering from tokenExpired
is to issue the user a new token, obviously making sure they aren't a nefarious actor. The way you issue a new token depends on the signer's type that was setup when the packet was created.
See the recovering from token errors section of the docs for full details!
Summary
With these improvements, you should have all the tools you need to provide a robust and deeply integrated signing experience for your users! Let us know if you have any questions at support@useanvil.com. We'd love to hear from you.