checkout: show the GoblinPay mark on the QR and the pay page
The hosted checkout page gains the GoblinPay wordmark header, and the QR center logo defaults to a new high-contrast GoblinPay mark (dark P on brand gold) instead of the generic goblin mark. Still overridable via GP_QR_LOGO (url/path/off); the legacy /static/goblin-mark.svg route is kept for operators who pinned it.
This commit is contained in:
@@ -17,7 +17,7 @@ carries the full merchant surface:
|
|||||||
invoice automatically.
|
invoice automatically.
|
||||||
- **Hosted checkout:** a zero-JS `/pay/<token>` page (server-rendered
|
- **Hosted checkout:** a zero-JS `/pay/<token>` page (server-rendered
|
||||||
Askama + one CSS file + a server-generated QR SVG at ECC level H with an
|
Askama + one CSS file + a server-generated QR SVG at ECC level H with an
|
||||||
optional Goblin-mark center logo), live status via `<meta http-equiv=refresh>`,
|
optional GoblinPay-mark center logo), live status via `<meta http-equiv=refresh>`,
|
||||||
and a manual slatepack fallback (paste S1 -> offline `receive_tx` -> copy the
|
and a manual slatepack fallback (paste S1 -> offline `receive_tx` -> copy the
|
||||||
S2 back) on every page. The same renderer serves embedded and hosted use.
|
S2 back) on every page. The same renderer serves embedded and hosted use.
|
||||||
- **Per-user endpubs:** an admin assigns one receiving identity per user
|
- **Per-user endpubs:** an admin assigns one receiving identity per user
|
||||||
@@ -75,7 +75,7 @@ Everything is environment variables, defaults are safe for local use.
|
|||||||
| `GP_ADMIN_TOKEN` | unset | Bearer token for the admin dashboard + endpub/webhook API |
|
| `GP_ADMIN_TOKEN` | unset | Bearer token for the admin dashboard + endpub/webhook API |
|
||||||
| `GP_WEBHOOK_URL` | unset | Webhook endpoint for payment events (requires `GP_WEBHOOK_SECRET`) |
|
| `GP_WEBHOOK_URL` | unset | Webhook endpoint for payment events (requires `GP_WEBHOOK_SECRET`) |
|
||||||
| `GP_WEBHOOK_SECRET` | unset | HMAC-SHA256 secret for signing webhooks |
|
| `GP_WEBHOOK_SECRET` | unset | HMAC-SHA256 secret for signing webhooks |
|
||||||
| `GP_QR_LOGO` | Goblin mark | Checkout QR center logo: unset = Goblin mark, `off`/`none` = plain, else a URL/path |
|
| `GP_QR_LOGO` | GoblinPay mark | Checkout QR center logo: unset = GoblinPay mark, `off`/`none` = plain, else a URL/path |
|
||||||
| `GP_MERCHANT_NPUB` | unset | Merchant npub for the NIP-17 confirmed-payment DM |
|
| `GP_MERCHANT_NPUB` | unset | Merchant npub for the NIP-17 confirmed-payment DM |
|
||||||
| `GP_NOTIFY_MERCHANT_DM` | `off` | Send a NIP-17 DM to the merchant on a received payment |
|
| `GP_NOTIFY_MERCHANT_DM` | `off` | Send a NIP-17 DM to the merchant on a received payment |
|
||||||
| `GP_NOTIFY_PAYER_RECEIPT` | `off` | Send a NIP-17 receipt DM to the payer |
|
| `GP_NOTIFY_PAYER_RECEIPT` | `off` | Send a NIP-17 receipt DM to the payer |
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ pub struct Config {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub webhook_secret: Option<Secret>,
|
pub webhook_secret: Option<Secret>,
|
||||||
/// Center-logo source for checkout QR codes (`GP_QR_LOGO`): unset = the
|
/// Center-logo source for checkout QR codes (`GP_QR_LOGO`): unset = the
|
||||||
/// bundled Goblin mark, `off`/`none` = no logo, else a URL or static path.
|
/// bundled GoblinPay mark, `off`/`none` = no logo, else a URL or static path.
|
||||||
pub qr_logo: Option<String>,
|
pub qr_logo: Option<String>,
|
||||||
/// Merchant npub for confirmed-payment DMs (`GP_MERCHANT_NPUB`).
|
/// Merchant npub for confirmed-payment DMs (`GP_MERCHANT_NPUB`).
|
||||||
pub merchant_npub: Option<String>,
|
pub merchant_npub: Option<String>,
|
||||||
@@ -213,7 +213,7 @@ pub const DEFAULT_RATE_CACHE_TTL: i64 = 60;
|
|||||||
pub const DEFAULT_QUOTE_TTL: i64 = 900;
|
pub const DEFAULT_QUOTE_TTL: i64 = 900;
|
||||||
|
|
||||||
/// Default center-logo path served by gp-server when `GP_QR_LOGO` is unset.
|
/// Default center-logo path served by gp-server when `GP_QR_LOGO` is unset.
|
||||||
pub const DEFAULT_QR_LOGO: &str = "/static/goblin-mark.svg";
|
pub const DEFAULT_QR_LOGO: &str = "/static/goblinpay-mark.svg";
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|||||||
@@ -44,19 +44,40 @@ async fn style() -> impl Responder {
|
|||||||
.body(include_str!("../../../static/style.css"))
|
.body(include_str!("../../../static/style.css"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The bundled Goblin mark, the default QR center logo.
|
/// The bundled Goblin mark (legacy default QR center logo; still served so an
|
||||||
|
/// operator can keep `GP_QR_LOGO=/static/goblin-mark.svg`).
|
||||||
async fn goblin_mark() -> impl Responder {
|
async fn goblin_mark() -> impl Responder {
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
.content_type("image/svg+xml")
|
.content_type("image/svg+xml")
|
||||||
.body(include_str!("../../../static/goblin-mark.svg"))
|
.body(include_str!("../../../static/goblin-mark.svg"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The GoblinPay mark, the default QR center logo (dark "P" on the brand gold,
|
||||||
|
/// sized for contrast on the QR's white backing).
|
||||||
|
async fn goblinpay_mark() -> impl Responder {
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.content_type("image/svg+xml")
|
||||||
|
.body(include_str!("../../../static/goblinpay-mark.svg"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The GoblinPay wordmark (white), shown as the checkout page header logo.
|
||||||
|
async fn goblinpay_wordmark() -> impl Responder {
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.content_type("image/svg+xml")
|
||||||
|
.body(include_str!("../../../static/goblinpay-wordmark.svg"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Route table, shared by `main` and the tests.
|
/// Route table, shared by `main` and the tests.
|
||||||
fn routes(cfg: &mut web::ServiceConfig) {
|
fn routes(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.route("/", web::get().to(index))
|
cfg.route("/", web::get().to(index))
|
||||||
.route("/health", web::get().to(health))
|
.route("/health", web::get().to(health))
|
||||||
.route("/static/style.css", web::get().to(style))
|
.route("/static/style.css", web::get().to(style))
|
||||||
.route("/static/goblin-mark.svg", web::get().to(goblin_mark));
|
.route("/static/goblin-mark.svg", web::get().to(goblin_mark))
|
||||||
|
.route("/static/goblinpay-mark.svg", web::get().to(goblinpay_mark))
|
||||||
|
.route(
|
||||||
|
"/static/goblinpay-wordmark.svg",
|
||||||
|
web::get().to(goblinpay_wordmark),
|
||||||
|
);
|
||||||
// Payment status + signed-receipt reads (public-by-token, M4).
|
// Payment status + signed-receipt reads (public-by-token, M4).
|
||||||
payments::configure(cfg);
|
payments::configure(cfg);
|
||||||
// Hosted checkout + manual slatepack (public-by-token, M5).
|
// Hosted checkout + manual slatepack (public-by-token, M5).
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="GoblinPay">
|
||||||
|
<rect width="64" height="64" rx="14" fill="#e9c542"/>
|
||||||
|
<path fill="#201d09" fill-rule="evenodd" d="M22 14H35a12 12 0 0 1 0 24H30V50H22ZM30 21H34a6 6 0 0 1 0 12H30Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 272 B |
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||||
|
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="600.000000pt" height="232.000000pt" viewBox="0 0 600.000000 232.000000"
|
||||||
|
preserveAspectRatio="xMidYMid meet">
|
||||||
|
<g transform="translate(0.000000,232.000000) scale(0.050000,-0.050000)"
|
||||||
|
fill="#ffffff" stroke="none">
|
||||||
|
<path d="M52 4522 c-131 -444 37 -874 416 -1064 l122 -61 -95 11 c-111 13
|
||||||
|
-226 67 -324 154 -83 72 -86 66 -28 -48 140 -278 398 -434 715 -434 197 0 331
|
||||||
|
45 362 120 62 150 316 340 520 391 271 67 273 570 2 813 -194 175 -626 253
|
||||||
|
-842 152 l-70 -33 91 -1 c191 -4 428 -112 506 -231 36 -53 15 -72 -26 -23 -89
|
||||||
|
108 -361 154 -623 104 -384 -72 -552 -22 -664 197 l-30 60 -32 -107z"/>
|
||||||
|
<path d="M4560 2533 l0 -1610 285 3 285 4 5 573 6 573 484 9 c534 10 636 29
|
||||||
|
838 158 583 370 592 1348 15 1718 -240 155 -320 167 -1163 175 l-755 7 0
|
||||||
|
-1610z m1450 1080 c389 -170 416 -801 42 -998 -75 -40 -118 -44 -497 -51
|
||||||
|
l-415 -8 0 554 0 554 395 -8 c319 -7 410 -15 475 -43z"/>
|
||||||
|
<path d="M3139 3938 c-92 -222 -202 -268 -639 -268 -462 0 -625 -70 -783 -338
|
||||||
|
-58 -100 -60 -71 -4 66 37 92 27 95 -96 29 -298 -160 -537 -548 -537 -871 0
|
||||||
|
-117 -1 -117 -150 -4 -124 94 -359 217 -456 240 l-55 13 43 -108 c23 -59 67
|
||||||
|
-230 98 -381 87 -422 215 -636 412 -686 l94 -23 -4 -152 c-8 -255 71 -431 252
|
||||||
|
-564 108 -79 133 -87 119 -36 -6 19 -16 75 -24 125 l-14 90 86 -87 c155 -155
|
||||||
|
391 -243 648 -243 238 1 257 17 94 80 -148 58 -352 193 -453 300 l-60 63 150
|
||||||
|
-81 c278 -149 618 -181 915 -86 79 25 130 33 138 20 43 -71 324 -122 433 -79
|
||||||
|
31 12 26 23 -37 83 -138 133 -143 166 -41 260 116 107 160 201 145 310 -11 78
|
||||||
|
-6 89 69 162 122 118 151 178 228 468 39 147 96 319 127 383 65 137 62 139
|
||||||
|
-143 85 -158 -41 -258 -93 -362 -188 l-84 -77 -33 95 c-42 118 -118 202 -181
|
||||||
|
202 -63 0 -316 127 -366 183 -21 23 -29 39 -18 34 11 -5 54 -25 96 -44 600
|
||||||
|
-273 1151 104 1154 791 l0 94 -101 -107 c-197 -209 -486 -299 -738 -231 l-88
|
||||||
|
23 64 51 c95 74 147 190 147 330 0 142 -10 158 -45 74z m-172 -1574 c115 -128
|
||||||
|
161 -505 71 -595 -162 -162 -289 -89 -286 164 3 327 112 544 215 431z m-1030
|
||||||
|
-33 c101 -52 201 -243 241 -459 71 -385 -574 -317 -668 70 -55 226 234 489
|
||||||
|
427 389z m1703 -77 c0 -181 -102 -341 -141 -222 l-24 74 -27 -63 c-47 -112
|
||||||
|
-128 -19 -128 146 0 76 37 97 54 31 12 -47 46 -54 46 -9 0 48 62 61 92 19 26
|
||||||
|
-35 27 -35 41 2 37 103 87 116 87 22z m-2770 -34 c16 -73 41 -77 58 -10 33
|
||||||
|
129 140 -19 128 -177 l-6 -83 -43 66 -42 66 -13 -51 c-14 -56 -66 -69 -85 -21
|
||||||
|
-17 45 -36 36 -61 -30 -50 -132 -103 -48 -68 108 39 175 108 243 132 132z
|
||||||
|
m1350 -837 c0 -123 205 -183 399 -116 109 38 122 31 46 -24 -212 -151 -633
|
||||||
|
-30 -516 148 43 65 71 62 71 -8z"/>
|
||||||
|
<path d="M7910 3299 c-533 -109 -818 -523 -817 -1189 0 -436 84 -696 300 -929
|
||||||
|
341 -369 1014 -413 1335 -88 l90 92 -13 -78 c-7 -42 -13 -99 -14 -127 l-1 -50
|
||||||
|
250 -6 c138 -3 270 -1 295 6 l45 11 0 1159 0 1160 -281 0 -281 0 14 -125 14
|
||||||
|
-125 -82 84 c-183 188 -531 271 -854 205z m590 -485 c333 -171 432 -878 177
|
||||||
|
-1262 -222 -336 -773 -264 -938 121 -297 691 196 1430 761 1141z"/>
|
||||||
|
<path d="M9680 3249 c0 -6 211 -496 469 -1090 l469 -1078 -84 -201 c-162 -386
|
||||||
|
-315 -476 -665 -388 l-49 12 0 -231 c0 -269 -11 -255 217 -268 402 -22 736
|
||||||
|
151 909 470 43 81 553 1429 994 2630 l57 155 -296 0 -295 0 -256 -730 c-141
|
||||||
|
-402 -260 -726 -265 -722 -5 5 -146 331 -314 725 l-305 717 -293 6 c-161 3
|
||||||
|
-293 0 -293 -7z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -31,6 +31,9 @@ main {
|
|||||||
|
|
||||||
main.admin { max-width: 60rem; }
|
main.admin { max-width: 60rem; }
|
||||||
|
|
||||||
|
.brand { display: block; }
|
||||||
|
.brandmark { height: 30px; width: auto; display: block; margin: 0 0 1.25rem; }
|
||||||
|
|
||||||
h1 { font-size: 1.5rem; margin: 0 0 0.5rem; }
|
h1 { font-size: 1.5rem; margin: 0 0 0.5rem; }
|
||||||
h2 { font-size: 1.05rem; margin: 1.75rem 0 0.5rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.04em; }
|
h2 { font-size: 1.05rem; margin: 1.75rem 0 0.5rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.04em; }
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="checkout">
|
<main class="checkout">
|
||||||
|
<a class="brand" href="/"><img class="brandmark" src="/static/goblinpay-wordmark.svg" alt="GoblinPay"></a>
|
||||||
<h1>Pay with Goblin</h1>
|
<h1>Pay with Goblin</h1>
|
||||||
<p class="amount">{{ info.amount_display }}</p>
|
<p class="amount">{{ info.amount_display }}</p>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user