diff --git a/web/static/js/verification.js b/web/static/js/verification.js
index bc20c8a..8f4f02c 100644
--- a/web/static/js/verification.js
+++ b/web/static/js/verification.js
@@ -4,7 +4,8 @@ import { api } from './api.js';
import { state } from './state.js';
import { escHtml, formatDateTime } from './utils.js';
-const POLL_MS = 5000;
+const POLL_MS = 30_000; // DocuSign rate-limit guidance: no more than once per 15 min in prod
+const POLL_TIMEOUT = 300_000; // 5 minutes — treat as manual quick-test only; prod should use DS Connect
const _envelopes = {}; // { adobeId: { envelopeId, status, sentAt, completedAt, polling } }
function getSettings() {
@@ -115,6 +116,9 @@ function _verifyRow(t, settings) {
} else if (env.status === 'voided') {
statusCell = 'Voided';
actionsCell = ``;
+ } else if (env.status === 'timeout') {
+ statusCell = 'Timed Out';
+ actionsCell = ``;
} else {
statusCell = `${escHtml(env.status || 'pending')}`;
}
@@ -211,19 +215,23 @@ function _startPolling(adobeId, envelopeId) {
const env = _envelopes[adobeId];
if (!env || env.polling) return;
env.polling = true;
+ const deadline = Date.now() + POLL_TIMEOUT;
const poll = async () => {
try {
const data = await api.verify.status(envelopeId);
- if (_envelopes[adobeId]) {
- _envelopes[adobeId].status = data.status;
- _envelopes[adobeId].completedAt = data.completed_at;
+ if (!_envelopes[adobeId]) return;
+ _envelopes[adobeId].status = data.status;
+ _envelopes[adobeId].completedAt = data.completed_at;
+ _updateVerifyRow(adobeId);
+ if (data.status === 'completed' || data.status === 'voided') {
+ _envelopes[adobeId].polling = false;
+ } else if (Date.now() >= deadline) {
+ _envelopes[adobeId].polling = false;
+ _envelopes[adobeId].status = 'timeout';
_updateVerifyRow(adobeId);
- if (data.status !== 'completed' && data.status !== 'voided') {
- setTimeout(poll, POLL_MS);
- } else {
- _envelopes[adobeId].polling = false;
- }
+ } else {
+ setTimeout(poll, POLL_MS);
}
} catch (e) {
console.warn('Polling error:', e.message);
@@ -252,6 +260,9 @@ function _updateVerifyRow(adobeId) {
} else if (env.status === 'voided') {
statusEl.innerHTML = 'Voided';
actionsEl.innerHTML = ``;
+ } else if (env.status === 'timeout') {
+ statusEl.innerHTML = 'Timed Out';
+ actionsEl.innerHTML = ``;
}
// Re-wire newly injected buttons