Diff -- /var/www/vhosts/webstls.com/httpdocs/stripe_connect.cgi
Diff

/var/www/vhosts/webstls.com/httpdocs/stripe_connect.cgi

added on WebSTLs (webstls.com) at 2026-07-01 22:26:47

Added
+166
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to e4ae904cf06b
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1#!/usr/bin/perl
2#======================================================================
3# WebSTLs - Stripe Connect: seller-side onboarding.
4#
5# Consolidates the former /stripe_connect_callback.cgi (Stripe return URL)
6# via SCRIPT_NAME dispatch. The .cgi=callback file is a wrapper that
7# `do`s this file. The callback URL must remain reachable at
8# /stripe_connect_callback.cgi because that URL is registered with Stripe.
9#
10# Flow:
11# GET /stripe_connect.cgi?storefront_id=N
12# -> creates a Stripe Express account if missing
13# -> creates an account link and 302s to Stripe-hosted onboarding
14#
15# GET /stripe_connect_callback.cgi?storefront_id=N
16# -> Stripe redirects the seller here after onboarding (return_url)
17# -> re-fetches the account, sets stripe_onboarded_at if enabled
18# -> 302s back to /storefront.cgi with a status flag
19#======================================================================
20use strict;
21use warnings;
22
23use lib '/var/www/vhosts/webstls.com/httpdocs';
24use CGI;
25use MODS::DBConnect;
26use MODS::Login;
27use MODS::WebSTLs::Config;
28use MODS::WebSTLs::Stripe;
29
30$| = 1;
31
32my $q = CGI->new;
33my $form = $q->Vars;
34my $auth = MODS::Login->new;
35my $db = MODS::DBConnect->new;
36my $cfg = MODS::WebSTLs::Config->new;
37my $DB = $cfg->settings('database_name');
38
39my $entry = ($ENV{SCRIPT_NAME} || '') =~ m{/([^/]+)\.cgi$} ? $1 : 'stripe_connect';
40
41# Auth per branch (both branches require login + owner).
42my $userinfo = $auth->login_verify();
43unless ($userinfo) {
44 print "Status: 302 Found\nLocation: /login.cgi\n\n";
45 exit;
46}
47require MODS::WebSTLs::Permissions;
48MODS::WebSTLs::Permissions->new->require_owner($userinfo);
49my $uid = $userinfo->{user_id};
50$uid =~ s/[^0-9]//g;
51
52my $sid = $form->{storefront_id} || $form->{id} || 0;
53$sid =~ s/[^0-9]//g;
54
55if ($entry eq 'stripe_connect_callback') {
56 _stc_handle_callback();
57 exit;
58}
59
60# ---------------------------------------------------------------- initiate
61my $stripe = MODS::WebSTLs::Stripe->new;
62unless ($stripe->is_configured) {
63 _stc_bail('Stripe is not configured on this server yet. Add keys to /private/stripe.conf.');
64}
65
66my $dbh = $db->db_connect();
67my $store = $db->db_readwrite($dbh, qq~
68 SELECT id, stripe_account_id
69 FROM `${DB}`.storefronts
70 WHERE id='$sid' AND user_id='$uid'
71 LIMIT 1
72~, $ENV{SCRIPT_NAME}, __LINE__);
73unless ($store && $store->{id}) {
74 $db->db_disconnect($dbh);
75 _stc_bail('Storefront not found.');
76}
77
78my $account_id = $store->{stripe_account_id} || '';
79
80# Create the connected account on first run.
81if (!$account_id) {
82 my $email = $userinfo->{email} || '';
83 my $acct = $stripe->create_express_account(
84 email => $email,
85 metadata => {
86 webstls_user_id => $uid,
87 webstls_storefront_id => $sid,
88 },
89 );
90 if ($acct->{error} || !$acct->{id}) {
91 $db->db_disconnect($dbh);
92 _stc_bail('Stripe account create failed: ' . ($acct->{error} || 'unknown'));
93 }
94 $account_id = $acct->{id};
95 $account_id =~ s/'/''/g;
96 $db->db_readwrite($dbh, qq~
97 UPDATE `${DB}`.storefronts
98 SET stripe_account_id='$account_id'
99 WHERE id='$sid' AND user_id='$uid'
100 ~, $ENV{SCRIPT_NAME}, __LINE__);
101}
102
103$db->db_disconnect($dbh);
104
105# Build absolute return URLs. Plesk fronts everything with HTTPS so
106# we hard-prefix https:// rather than reading $ENV{HTTPS}.
107my $host = $ENV{HTTP_HOST} || 'webstls.com';
108my $base = "https://$host";
109my $link = $stripe->create_account_link(
110 account => $account_id,
111 refresh_url => "$base/stripe_connect.cgi?storefront_id=$sid",
112 return_url => "$base/stripe_connect_callback.cgi?storefront_id=$sid",
113);
114if ($link->{error} || !$link->{url}) {
115 _stc_bail('Stripe account link failed: ' . ($link->{error} || 'unknown'));
116}
117
118print "Status: 302 Found\nLocation: " . $link->{url} . "\n\n";
119exit;
120
121#======================================================================
122# stripe_connect_callback entry: Stripe return URL handler.
123#======================================================================
124sub _stc_handle_callback {
125 my $dbh = $db->db_connect();
126 my $store = $db->db_readwrite($dbh, qq~
127 SELECT id, stripe_account_id
128 FROM `${DB}`.storefronts
129 WHERE id='$sid' AND user_id='$uid'
130 LIMIT 1
131 ~, $ENV{SCRIPT_NAME}, __LINE__);
132
133 my $msg = '';
134 if ($store && $store->{stripe_account_id}) {
135 my $stripe = MODS::WebSTLs::Stripe->new;
136 if ($stripe->is_configured) {
137 my $acct = $stripe->retrieve_account($store->{stripe_account_id});
138 if (!$acct->{error} && $acct->{charges_enabled} && $acct->{details_submitted}) {
139 $db->db_readwrite($dbh, qq~
140 UPDATE `${DB}`.storefronts
141 SET stripe_onboarded_at=NOW()
142 WHERE id='$sid' AND user_id='$uid'
143 ~, $ENV{SCRIPT_NAME}, __LINE__);
144 $msg = 'stripe_connected=1';
145 } else {
146 $msg = 'stripe_pending=1';
147 }
148 }
149 }
150 $db->db_disconnect($dbh);
151
152 print "Status: 302 Found\nLocation: /storefront.cgi?$msg\n\n";
153 return;
154}
155
156sub _stc_bail {
157 my ($msg) = @_;
158 print "Status: 302 Found\nLocation: /storefront.cgi?stripe_error=" . _stc_urlenc($msg) . "\n\n";
159 exit;
160}
161
162sub _stc_urlenc {
163 my $s = shift // '';
164 $s =~ s/([^A-Za-z0-9\-._~])/sprintf('%%%02X', ord($1))/ge;
165 return $s;
166}
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help