fix: dolares
All checks were successful
Deploy QR Rapido / test (push) Successful in 1m4s
Deploy QR Rapido / build-and-push (push) Successful in 17m23s
Deploy QR Rapido / deploy-staging (push) Has been skipped
Deploy QR Rapido / deploy-production (push) Successful in 2m45s

This commit is contained in:
Ricardo Carneiro 2026-05-08 08:23:07 -03:00
parent fb466a71b8
commit 9161977f85
2 changed files with 61 additions and 39 deletions

View File

@ -126,21 +126,27 @@ namespace QRRapidoApp.Controllers
{ {
// Create Stripe Checkout Session (One-Time Payment) // Create Stripe Checkout Session (One-Time Payment)
// We create an ad-hoc price on the fly using line_items // We create an ad-hoc price on the fly using line_items
var useUsd = string.Equals(request.Currency, "usd", StringComparison.OrdinalIgnoreCase);
var currency = useUsd ? "usd" : "brl";
var unitAmount = useUsd
? (long)(package.PriceUsd * 100)
: (long)(package.PriceCard * 100);
var options = new SessionCreateOptions var options = new SessionCreateOptions
{ {
PaymentMethodTypes = new List<string> { "card" }, PaymentMethodTypes = new List<string> { "card" },
Mode = "payment", // One-time payment Mode = "payment",
LineItems = new List<SessionLineItemOptions> LineItems = new List<SessionLineItemOptions>
{ {
new SessionLineItemOptions new SessionLineItemOptions
{ {
PriceData = new SessionLineItemPriceDataOptions PriceData = new SessionLineItemPriceDataOptions
{ {
Currency = "brl", Currency = currency,
UnitAmount = (long)(package.PriceCard * 100), // Centavos UnitAmount = unitAmount,
ProductData = new SessionLineItemPriceDataProductDataOptions ProductData = new SessionLineItemPriceDataProductDataOptions
{ {
Name = $"{package.Credits} Créditos QR Rapido", Name = $"{package.Credits} QR Rapido Credits",
Description = package.Description Description = package.Description
} }
}, },
@ -177,8 +183,9 @@ namespace QRRapidoApp.Controllers
Id = "starter", Id = "starter",
Name = "Iniciante", Name = "Iniciante",
Credits = 10, Credits = 10,
PricePix = 5.00m, // R$ 0,50/un PricePix = 5.00m,
PriceCard = 6.00m, PriceCard = 6.00m,
PriceUsd = 1.09m,
Description = "Ideal para testes rápidos", Description = "Ideal para testes rápidos",
Savings = 0 Savings = 0
}, },
@ -186,8 +193,9 @@ namespace QRRapidoApp.Controllers
Id = "pro", Id = "pro",
Name = "Profissional", Name = "Profissional",
Credits = 50, Credits = 50,
PricePix = 22.50m, // R$ 0,45/un (Desconto de volume) PricePix = 22.50m,
PriceCard = 27.00m, PriceCard = 27.00m,
PriceUsd = 4.99m,
Description = "Para uso recorrente", Description = "Para uso recorrente",
Savings = 10, Savings = 10,
IsPopular = true IsPopular = true
@ -196,8 +204,9 @@ namespace QRRapidoApp.Controllers
Id = "agency", Id = "agency",
Name = "Agência", Name = "Agência",
Credits = 100, Credits = 100,
PricePix = 40.00m, // R$ 0,40/un (Super desconto) PricePix = 40.00m,
PriceCard = 48.00m, PriceCard = 48.00m,
PriceUsd = 8.99m,
Description = "Volume alto com desconto máximo", Description = "Volume alto com desconto máximo",
Savings = 20 Savings = 20
} }
@ -212,6 +221,7 @@ namespace QRRapidoApp.Controllers
public class CreateOrderRequest public class CreateOrderRequest
{ {
public string PackageId { get; set; } public string PackageId { get; set; }
public string Currency { get; set; } = "brl"; // "brl" or "usd"
} }
public class CreditPackageViewModel public class CreditPackageViewModel
@ -219,8 +229,9 @@ namespace QRRapidoApp.Controllers
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public int Credits { get; set; } public int Credits { get; set; }
public decimal PricePix { get; set; } // Preço PIX public decimal PricePix { get; set; } // Preço PIX (BRL only)
public decimal PriceCard { get; set; } // Preço Cartão (+taxas) public decimal PriceCard { get; set; } // Preço Cartão BRL
public decimal PriceUsd { get; set; } // Preço Cartão USD
public string Description { get; set; } public string Description { get; set; }
public int Savings { get; set; } public int Savings { get; set; }
public bool IsPopular { get; set; } public bool IsPopular { get; set; }

View File

@ -35,7 +35,7 @@
<span class="text-muted d-block">QR Codes</span> <span class="text-muted d-block">QR Codes</span>
</div> </div>
<!-- Preços Duplos --> <!-- Preços -->
<div class="bg-light rounded p-3 mb-4"> <div class="bg-light rounded p-3 mb-4">
@if (isBrazilian) @if (isBrazilian)
{ {
@ -43,11 +43,19 @@
<span class="text-muted"><i class="fas fa-bolt text-warning"></i> PIX</span> <span class="text-muted"><i class="fas fa-bolt text-warning"></i> PIX</span>
<span class="h4 text-success mb-0 fw-bold">R$ @package.PricePix.ToString("F2")</span> <span class="h4 text-success mb-0 fw-bold">R$ @package.PricePix.ToString("F2")</span>
</div> </div>
}
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<span class="text-muted"><i class="fas fa-credit-card"></i> @(isBrazilian ? "Cartão" : "Card")</span> <span class="text-muted"><i class="fas fa-credit-card"></i> Cartão</span>
<span class="h5 text-secondary mb-0">@(isBrazilian ? "R$" : "BRL") @package.PriceCard.ToString("F2")</span> <span class="h5 text-secondary mb-0">R$ @package.PriceCard.ToString("F2")</span>
</div> </div>
}
else
{
<div class="d-flex justify-content-between align-items-center">
<span class="text-muted"><i class="fas fa-credit-card"></i> Card</span>
<span class="h4 text-success mb-0 fw-bold">$ @package.PriceUsd.ToString("F2")</span>
</div>
<div class="text-muted small mt-1">USD · charged via Stripe</div>
}
</div> </div>
<ul class="list-unstyled text-start mb-4 mx-auto" style="max-width: 250px;"> <ul class="list-unstyled text-start mb-4 mx-auto" style="max-width: 250px;">
@ -67,8 +75,10 @@
</button> </button>
} }
<button class="btn @(package.IsPopular ? "btn-primary" : "btn-outline-primary") btn-card-checkout" <button class="btn @(package.IsPopular ? "btn-primary" : "btn-outline-primary") btn-card-checkout"
data-package-id="@package.Id"> data-package-id="@package.Id"
<i class="fas fa-credit-card me-2"></i> Pagar com Cartão data-currency="@(isBrazilian ? "brl" : "usd")">
<i class="fas fa-credit-card me-2"></i>
@(isBrazilian ? "Pagar com Cartão" : "Pay with Card")
</button> </button>
</div> </div>
} }
@ -197,10 +207,11 @@
this.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span> Redirecionando...'; this.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span> Redirecionando...';
try { try {
const currency = this.dataset.currency || 'brl';
const response = await fetch('/api/Pagamento/CreateStripeSession', { const response = await fetch('/api/Pagamento/CreateStripeSession', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ packageId: packageId }) body: JSON.stringify({ packageId: packageId, currency: currency })
}); });
const result = await response.json(); const result = await response.json();