feat(domain): configurar soporte oficial para dominio drip-zone.online en Traefik, Bold y App Android
This commit is contained in:
parent
182b2600c0
commit
6657525815
@ -21,10 +21,24 @@ import java.util.concurrent.TimeUnit
|
|||||||
object ApiClient {
|
object ApiClient {
|
||||||
|
|
||||||
private const val TAG = "DripApiClient"
|
private const val TAG = "DripApiClient"
|
||||||
private const val PRIMARY_URL = "https://dripzone.almeira.com.co/api/products"
|
|
||||||
private const val FALLBACK_URL = "https://news.almeira.com.co/api/products"
|
|
||||||
private const val CACHE_KEY_PRODUCTS = "cached_products_json"
|
private const val CACHE_KEY_PRODUCTS = "cached_products_json"
|
||||||
|
|
||||||
|
fun getBaseUrl(): String {
|
||||||
|
return try {
|
||||||
|
val addr = java.net.InetAddress.getByName("drip-zone.online")
|
||||||
|
if (addr != null && !addr.hostAddress.isNullOrBlank()) {
|
||||||
|
"https://drip-zone.online"
|
||||||
|
} else {
|
||||||
|
"https://dripzone.almeira.com.co"
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"https://dripzone.almeira.com.co"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPrimaryProductsUrl(): String = "${getBaseUrl()}/api/products"
|
||||||
|
private const val FALLBACK_URL = "https://news.almeira.com.co/api/products"
|
||||||
|
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|
||||||
// OkHttpClient enforcing TLS 1.3 and TLS 1.2 modern cipher suites
|
// OkHttpClient enforcing TLS 1.3 and TLS 1.2 modern cipher suites
|
||||||
@ -48,7 +62,7 @@ object ApiClient {
|
|||||||
suspend fun getProducts(context: Context, forceRefresh: Boolean = false): List<Product> =
|
suspend fun getProducts(context: Context, forceRefresh: Boolean = false): List<Product> =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
// 1. Try primary URL
|
// 1. Try primary URL
|
||||||
val primaryResult = fetchFromUrl(PRIMARY_URL)
|
val primaryResult = fetchFromUrl(getPrimaryProductsUrl())
|
||||||
if (primaryResult != null && primaryResult.isNotEmpty()) {
|
if (primaryResult != null && primaryResult.isNotEmpty()) {
|
||||||
saveCache(context, primaryResult)
|
saveCache(context, primaryResult)
|
||||||
return@withContext primaryResult
|
return@withContext primaryResult
|
||||||
@ -208,7 +222,7 @@ object ApiClient {
|
|||||||
val requestBody = jsonPayload.toRequestBody(mediaType)
|
val requestBody = jsonPayload.toRequestBody(mediaType)
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("https://dripzone.almeira.com.co/api/auth/send-otp")
|
.url("${getBaseUrl()}/api/auth/send-otp")
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
@ -256,7 +270,7 @@ object ApiClient {
|
|||||||
val requestBody = jsonPayload.toRequestBody(mediaType)
|
val requestBody = jsonPayload.toRequestBody(mediaType)
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("https://dripzone.almeira.com.co/api/auth/verify-otp")
|
.url("${getBaseUrl()}/api/auth/verify-otp")
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
@ -289,7 +303,7 @@ object ApiClient {
|
|||||||
val requestBody = jsonPayload.toRequestBody(mediaType)
|
val requestBody = jsonPayload.toRequestBody(mediaType)
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("https://dripzone.almeira.com.co/api/orders")
|
.url("${getBaseUrl()}/api/orders")
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
@ -324,7 +338,7 @@ object ApiClient {
|
|||||||
val requestBody = jsonPayload.toRequestBody(mediaType)
|
val requestBody = jsonPayload.toRequestBody(mediaType)
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("https://dripzone.almeira.com.co/api/custom-requests")
|
.url("${getBaseUrl()}/api/custom-requests")
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
@ -370,7 +384,7 @@ object ApiClient {
|
|||||||
val requestBody = jsonPayload.toRequestBody(mediaType)
|
val requestBody = jsonPayload.toRequestBody(mediaType)
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("https://dripzone.almeira.com.co/api/bold/create-payment")
|
.url("${getBaseUrl()}/api/bold/create-payment")
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
@ -403,7 +417,7 @@ object ApiClient {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("https://dripzone.almeira.com.co/api/bold/status?linkId=$linkId&orderId=$orderId")
|
.url("${getBaseUrl()}/api/bold/status?linkId=$linkId&orderId=$orderId")
|
||||||
.get()
|
.get()
|
||||||
.header("Accept", "application/json")
|
.header("Accept", "application/json")
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
<domain-config cleartextTrafficPermitted="false">
|
<domain-config cleartextTrafficPermitted="false">
|
||||||
<domain includeSubdomains="true">almeira.com.co</domain>
|
<domain includeSubdomains="true">almeira.com.co</domain>
|
||||||
<domain includeSubdomains="true">dripzone.almeira.com.co</domain>
|
<domain includeSubdomains="true">dripzone.almeira.com.co</domain>
|
||||||
|
<domain includeSubdomains="true">drip-zone.online</domain>
|
||||||
<domain includeSubdomains="true">news.almeira.com.co</domain>
|
<domain includeSubdomains="true">news.almeira.com.co</domain>
|
||||||
<domain includeSubdomains="true">cloud.appwrite.io</domain>
|
<domain includeSubdomains="true">cloud.appwrite.io</domain>
|
||||||
<domain includeSubdomains="true">wa.me</domain>
|
<domain includeSubdomains="true">wa.me</domain>
|
||||||
|
|||||||
@ -35,11 +35,11 @@ services:
|
|||||||
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
|
||||||
- "traefik.http.routers.dripzone-http.entryPoints=http"
|
- "traefik.http.routers.dripzone-http.entryPoints=http"
|
||||||
- "traefik.http.routers.dripzone-http.middlewares=redirect-to-https"
|
- "traefik.http.routers.dripzone-http.middlewares=redirect-to-https"
|
||||||
- "traefik.http.routers.dripzone-http.rule=Host(`dripzone.almeira.com.co`) && PathPrefix(`/`)"
|
- "traefik.http.routers.dripzone-http.rule=Host(`drip-zone.online`) || Host(`www.drip-zone.online`) || Host(`dripzone.almeira.com.co`)"
|
||||||
- "traefik.http.routers.dripzone-http.service=dripzone-svc"
|
- "traefik.http.routers.dripzone-http.service=dripzone-svc"
|
||||||
- "traefik.http.routers.dripzone-https.entryPoints=https"
|
- "traefik.http.routers.dripzone-https.entryPoints=https"
|
||||||
- "traefik.http.routers.dripzone-https.middlewares=gzip"
|
- "traefik.http.routers.dripzone-https.middlewares=gzip"
|
||||||
- "traefik.http.routers.dripzone-https.rule=Host(`dripzone.almeira.com.co`) && PathPrefix(`/`)"
|
- "traefik.http.routers.dripzone-https.rule=Host(`drip-zone.online`) || Host(`www.drip-zone.online`) || Host(`dripzone.almeira.com.co`)"
|
||||||
- "traefik.http.routers.dripzone-https.service=dripzone-svc"
|
- "traefik.http.routers.dripzone-https.service=dripzone-svc"
|
||||||
- "traefik.http.routers.dripzone-https.tls=true"
|
- "traefik.http.routers.dripzone-https.tls=true"
|
||||||
- "traefik.http.routers.dripzone-https.tls.certresolver=letsencrypt"
|
- "traefik.http.routers.dripzone-https.tls.certresolver=letsencrypt"
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export async function POST(request: Request) {
|
|||||||
amount: Number(amount),
|
amount: Number(amount),
|
||||||
description,
|
description,
|
||||||
payerEmail,
|
payerEmail,
|
||||||
redirectionUrl: redirectionUrl || `https://dripzone.almeira.com.co/checkout?orderId=${orderId}`,
|
redirectionUrl: redirectionUrl || `https://drip-zone.online/checkout?orderId=${orderId}`,
|
||||||
type,
|
type,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,7 @@ def main():
|
|||||||
print(" [OK] Archivos sincronizados en VPS.")
|
print(" [OK] Archivos sincronizados en VPS.")
|
||||||
|
|
||||||
print("[3/5] Reconstruyendo y reiniciando contenedor en VPS (docker compose build)...")
|
print("[3/5] Reconstruyendo y reiniciando contenedor en VPS (docker compose build)...")
|
||||||
cmd_build = f"cd {REMOTE_BASE} && docker compose -f docker-compose.prod.yml up -d --build"
|
cmd_build = f"cd {REMOTE_BASE} && echo {PASSWORD} | sudo -S docker compose -f docker-compose.prod.yml build && echo {PASSWORD} | sudo -S docker compose -f docker-compose.prod.yml up -d"
|
||||||
stdin, stdout, stderr = ssh.exec_command(cmd_build)
|
stdin, stdout, stderr = ssh.exec_command(cmd_build)
|
||||||
out = stdout.read().decode('utf-8', errors='replace')
|
out = stdout.read().decode('utf-8', errors='replace')
|
||||||
err = stderr.read().decode('utf-8', errors='replace')
|
err = stderr.read().decode('utf-8', errors='replace')
|
||||||
@ -115,20 +115,23 @@ def main():
|
|||||||
|
|
||||||
print("[5/5] Enviando notificación detallada y archivo APK al WhatsApp de Carlos (+57 316 745 5877)...")
|
print("[5/5] Enviando notificación detallada y archivo APK al WhatsApp de Carlos (+57 316 745 5877)...")
|
||||||
message_text = (
|
message_text = (
|
||||||
"🚀 *DripZone v1.5 - Pasarela de Pagos Bold & QR Bre-B Integrados*\n\n"
|
"🚀 *DripZone v1.5 - Dominio drip-zone.online & Pasarela Bold Bre-B*\n\n"
|
||||||
"Hola Carlos, se ha completado e implementado en producción la integración integral de la pasarela oficial *Bold*:\n\n"
|
"Hola Carlos, se ha implementado en producción la configuración completa:\n\n"
|
||||||
"💳 *1. Cobro de Separación con QR Bre-B y Pasarela Bold:*\n"
|
"🌐 *1. Dominio Oficial drip-zone.online:*\n"
|
||||||
"• Al registrar el primer pedido, la plataforma genera automáticamente una orden de cobro en Bold por *$10.000 COP*.\n"
|
"• Configurado el servidor de producción (Traefik y Docker) para responder en *drip-zone.online*, *www.drip-zone.online* y el alias de respaldo `dripzone.almeira.com.co`.\n"
|
||||||
"• Tanto en la Web como en la App Nativa se renderiza en vivo el *Código QR Bre-B*, permitiendo escanear y pagar al instante desde Bancolombia, Nequi, Daviplata, Dale o cualquier app bancaria interoperable.\n"
|
"• Certificados SSL automáticos (Let's Encrypt) habilitados.\n"
|
||||||
"• Incluye botón directo para pagar con tarjeta de crédito/débito o PSE en el checkout alojado seguro de Bold.\n\n"
|
"• *Paso restante en tu registrador:* Asegúrate de apuntar los registros A de `drip-zone.online` y `www.drip-zone.online` a la IP del VPS: `161.97.93.156`.\n\n"
|
||||||
"⚡ *2. Acreditación Automática en Tiempo Real:*\n"
|
"💳 *2. Cobro de Separación con QR Bre-B y Pasarela Bold:*\n"
|
||||||
"• El sistema cuenta con sondeo continuo (polling de 3 segundos) y Webhook (`/api/webhook/bold`) para capturar la aprobación del pago inmediatamente.\n"
|
"• Al registrar el pedido, se genera la orden de cobro en Bold por *$10.000 COP*.\n"
|
||||||
"• En cuanto el cliente paga, la pantalla confirma el abono en verde al instante, la orden pasa a estado `deposit_received`, se resta automáticamente el saldo a pagar contraentrega y se te envía notificación inmediata con los datos del pago.\n\n"
|
"• En la Web y en la App Nativa se renderiza en tiempo real el *Código QR Bre-B*, permitiendo escanear y pagar al instante desde Bancolombia, Nequi, Daviplata o cualquier banco.\n"
|
||||||
"🔑 *3. Modo de Pruebas Activo (Sandbox):*\n"
|
"• Incluye botón directo al checkout seguro de Bold para tarjetas de crédito/débito o PSE.\n\n"
|
||||||
"• La pasarela está operando actualmente con las llaves de prueba de la API (`GatyXH...` / `BAFlCP...`) para validar el ciclo completo con transacciones simuladas sin costo.\n"
|
"⚡ *3. Acreditación Automática en Tiempo Real:*\n"
|
||||||
"• Las llaves de producción ya quedaron preconfiguradas en el servidor y listas para encender en cuanto des la orden.\n\n"
|
"• Detección inmediata en vivo con Webhook (`/api/webhook/bold`) y sondeo reactivo.\n"
|
||||||
"📲 *4. App Nativa Android v1.5 Sincronizada:*\n"
|
"• Cuando el cliente paga, la orden pasa a `deposit_received`, se descuenta el anticipo del saldo contraentrega y se te envía notificación inmediata con los datos del pago.\n\n"
|
||||||
"• Nuevo APK compilado con el módulo de lectura de QR Bre-B, botón a Bold y confirmación reactiva en vivo.\n\n"
|
"🔑 *4. Modo Sandbox Activo para Pruebas:*\n"
|
||||||
|
"• Operando con las llaves de prueba de la API (`GatyXH...` / `BAFlCP...`) para pruebas sin costo. Las llaves de producción ya están listas para activarse.\n\n"
|
||||||
|
"📲 *5. App Nativa Android v1.5:*\n"
|
||||||
|
"• Compilada con soporte dinámico para `drip-zone.online` y QR Bre-B.\n\n"
|
||||||
f"🔗 *Descarga Directa:* {APK_URL}\n\n"
|
f"🔗 *Descarga Directa:* {APK_URL}\n\n"
|
||||||
"Te adjunto el APK compilado para que puedas instalarlo y probar la experiencia de usuario."
|
"Te adjunto el APK compilado para que puedas instalarlo y probar la experiencia de usuario."
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user