Clarify 20-min rental ceiling (verified: SMSPool ignores expiry param)

- sms.py: drop misleading expiry param from /purchase/sms (SMSPool hard-caps
  rentals at 1200s/20min regardless); document MAX_RENTAL_MIN as verified
- surface the ceiling in customer UI + admin panel + feasibility doc
This commit is contained in:
drjones
2026-09-20 20:11:08 -07:00
parent 48305b4ad1
commit d7ce96fba4
3 changed files with 8 additions and 4 deletions

9
sms.py
View File

@@ -77,8 +77,9 @@ class SMSPoolProvider(NumberProvider):
return self._get("service/retrieve_all", {}) return self._get("service/retrieve_all", {})
def provision_number(self, service, country, expiry_min): def provision_number(self, service, country, expiry_min):
return self._get("purchase/sms", {"service": service, "country": country, # `expiry` is passed for API compatibility but SMSPool ignores it —
"expiry": int(expiry_min)}) # every rental hard-caps at 20 min (see MAX_RENTAL_MIN).
return self._get("purchase/sms", {"service": service, "country": country})
def check_sms(self, order_id): def check_sms(self, order_id):
return self._get("sms/check", {"orderid": order_id}) return self._get("sms/check", {"orderid": order_id})
@@ -132,7 +133,9 @@ DEFAULT_PRICING = [
{"duration_min": 20, "price_sats": 3000}, {"duration_min": 20, "price_sats": 3000},
] ]
MAX_RENTAL_MIN = 20 # SMSPool rental window ceiling; longer durations re-rent MAX_RENTAL_MIN = 20 # VERIFIED 2026-09-20: SMSPool ignores `expiry` param — rental numbers
# hard-cap at 1200s (20 min) regardless of what's requested. Longer
# sessions require a re-rent loop (not yet implemented).
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Schema # Schema

View File

@@ -6,6 +6,7 @@
<h1>Temporary <b>SMS</b></h1> <h1>Temporary <b>SMS</b></h1>
<p class="sub">Rent a real number for a few minutes to receive a verification code. No outbound. Pay with your wallet balance.</p> <p class="sub">Rent a real number for a few minutes to receive a verification code. No outbound. Pay with your wallet balance.</p>
<p class="disclaimer">Availability depends on the service you're verifying with. Some services reject temporary, VoIP, or recycled numbers.</p> <p class="disclaimer">Availability depends on the service you're verifying with. Some services reject temporary, VoIP, or recycled numbers.</p>
<p class="disclaimer">Rentals are capped at <b>20 minutes</b> (provider limit).</p>
</header> </header>
{% if session %} {% if session %}

View File

@@ -3,7 +3,7 @@
{% block body %} {% block body %}
<div style="max-width:900px;margin:0 auto;padding:24px 0"> <div style="max-width:900px;margin:0 auto;padding:24px 0">
<h1 style="font-size:1.9rem;letter-spacing:-.5px">SMS <b style="color:#0ff">Admin</b></h1> <h1 style="font-size:1.9rem;letter-spacing:-.5px">SMS <b style="color:#0ff">Admin</b></h1>
<p style="color:#94a3b8;margin:6px 0 16px">SMSPool balance: <b style="color:#0ff">{{ smspool_balance if smspool_balance is not none else 'unavailable' }} USD</b></p> <p style="color:#94a3b8;margin:6px 0 16px">SMSPool balance: <b style="color:#0ff">{{ smspool_balance if smspool_balance is not none else 'unavailable' }} USD</b> · <span style="color:#f59e0b">Rental ceiling: 20 min (SMSPool hard cap — longer sessions need a re-rent loop)</span></p>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:20px"> <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:20px">
<div style="background:rgba(20,28,40,.6);border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:14px"><div style="font-size:.7rem;color:#94a3b8;letter-spacing:.1em">ACTIVE</div><div style="font-size:1.6rem;color:#fff">{{ stats.active }}</div></div> <div style="background:rgba(20,28,40,.6);border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:14px"><div style="font-size:.7rem;color:#94a3b8;letter-spacing:.1em">ACTIVE</div><div style="font-size:1.6rem;color:#fff">{{ stats.active }}</div></div>