using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Shared; using Shared.Engine; using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using IO = System.IO.File; namespace Merchant.Controllers { /// /// https://pay.b2pay.io/merchant/api.php /// public class B2PAY : MerchantController { static B2PAY() { Directory.CreateDirectory("merchant/invoice/b2pay"); } [HttpGet] [AllowAnonymous] [Route("b2pay/new")] async public Task Index(string email) { if (!AppInit.conf.Merchant.B2PAY.enable || string.IsNullOrWhiteSpace(email)) return Content(string.Empty); Dictionary payment = new Dictionary() { ["amount"] = AppInit.conf.Merchant.accessCost, ["currency"] = "USD", ["description"] = "Buy Premium", ["order_number"] = CrypTo.md5(DateTime.Now.ToBinary().ToString()), ["type_payment"] = "merchant", ["usr"] = "new", ["custom_field"] = decodeEmail(email), ["callback_url"] = CrypTo.Base64($"{AppInit.Host(HttpContext)}/b2pay/callback"), ["success_url"] = CrypTo.Base64($"{AppInit.Host(HttpContext)}/buy/success.html"), ["error_url"] = CrypTo.Base64($"{AppInit.Host(HttpContext)}/buy/error.html") }; payment.Add("signature", CrypTo.Base64(CrypTo.md5binary($"{AppInit.conf.Merchant.accessCost}:{payment["callback_url"]}:{payment["currency"]}:{payment["custom_field"]}:{payment["description"]}:{payment["error_url"]}:{payment["order_number"]}:{payment["success_url"]}:merchant:new:{AppInit.conf.Merchant.B2PAY.encryption_password}"))); string data = $"payment={CrypTo.Base64(CrypTo.AES256(JsonConvert.SerializeObject(payment), AppInit.conf.Merchant.B2PAY.encryption_password, AppInit.conf.Merchant.B2PAY.encryption_iv))}&id={AppInit.conf.Merchant.B2PAY.username_id}"; var root = await Http.Post(AppInit.conf.Merchant.B2PAY.sandbox ? "https://pay.b2pay.io/api_sandbox/merchantpayments.php" : "https://pay.b2pay.io/api/merchantpayments.php", data); if (root == null || !root.ContainsKey("data")) return Content("data == null"); string invoiceurl = root.Value("data")?.Value("url"); if (string.IsNullOrWhiteSpace(invoiceurl)) return Content("invoiceurl == null"); IO.WriteAllText($"merchant/invoice/b2pay/{payment["order_number"]}", JsonConvert.SerializeObject(payment)); return Redirect(invoiceurl); } [HttpPost] [AllowAnonymous] [Route("b2pay/callback")] async public Task Callback() { if (!AppInit.conf.Merchant.B2PAY.enable || HttpContext.Request.Method != HttpMethods.Post || HttpContext.Request.ContentLength == 0) return StatusCode(404); var buffer = new byte[Convert.ToInt32(HttpContext.Request.ContentLength)]; await HttpContext.Request.Body.ReadAsync(buffer, 0, buffer.Length); var requestContent = Encoding.UTF8.GetString(buffer); WriteLog("b2pay", requestContent); JObject result = JsonConvert.DeserializeObject(requestContent); string signature = CrypTo.Base64(CrypTo.md5binary($"{result.Value("amount")}:{result.Value("currency")}:{result.Value("gatewayAmount")}:{result.Value("gatewayCurrency")}:{result.Value("gatewayRate")}:{result.Value("orderNumber")}:{result.Value("pay_id")}:{result.Value("sanitizedMask")}:{result.Value("status")}:{result.Value("token")}:pay:{AppInit.conf.Merchant.B2PAY.encryption_password}")); if (result.Value("sign") != signature) return StatusCode(401); string orderNumber = result.Value("orderNumber"); if (result.Value("status") != "approved" || string.IsNullOrWhiteSpace(orderNumber) || !IO.Exists($"merchant/invoice/b2pay/{orderNumber}")) return StatusCode(403); var invoice = JsonConvert.DeserializeObject>(IO.ReadAllText($"merchant/invoice/b2pay/{orderNumber}")); PayConfirm(invoice["custom_field"], "b2pay", orderNumber); return Content("ok"); } } }