Skip to content

Commit ce93ed1

Browse files
smarcetCopilot
andcommitted
feat: add generic parsing of payment method info at summit order (#338)
* feat: add generic parsing of payment method info at summit order * Update database/migrations/model/Version20250731013533.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update app/Services/Apis/PaymentGateways/StripeApi.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore: move all hardcoded values to IPaymentGatewayAPI constants fix: add code at SummitOrder to set up the cc info ( back compat ) * fix: add alipay type fix: return of nullable SummitOrder::getPaymentInfoDetails * feat: add job to ingest missing payment info for order from summits not ended yet --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1eddb6a commit ce93ed1

14 files changed

Lines changed: 432 additions & 56 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php namespace App\Console\Commands;
2+
/**
3+
* Copyright 2019 OpenStack Foundation
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
**/
14+
15+
use App\Services\Model\ISummitOrderService;
16+
use Illuminate\Console\Command;
17+
use Illuminate\Support\Facades\Log;
18+
19+
/**
20+
* Class IngestSummitOrderPaymentInfoCommand
21+
* @package App\Console\Commands
22+
*/
23+
final class IngestSummitOrderPaymentInfoCommand extends Command {
24+
25+
/**
26+
* The console command name.
27+
*
28+
* @var string
29+
*/
30+
protected $name = 'summit:registration-orders-payment-info-ingest';
31+
32+
/**
33+
* The name and signature of the console command.
34+
*
35+
* @var string
36+
*/
37+
protected $signature = 'summit:registration-orders-payment-info-ingest';
38+
39+
40+
/**
41+
* The console command description.
42+
*
43+
* @var string
44+
*/
45+
protected $description = 'Ingest missing payment info from Summit registration Orders';
46+
47+
48+
/**
49+
* @var ISummitOrderService
50+
*/
51+
private $order_service;
52+
53+
/**
54+
* RegistrationSummitOrderRevocationCommand constructor.
55+
* @param ISummitOrderService $order_service
56+
*/
57+
public function __construct(ISummitOrderService $order_service)
58+
{
59+
parent::__construct();
60+
$this->order_service = $order_service;
61+
}
62+
63+
/**
64+
* Execute the console command.
65+
*
66+
* @return mixed
67+
*/
68+
public function handle()
69+
{
70+
71+
72+
try {
73+
$this->info("processing summit orders with missing payment info");
74+
$start = time();
75+
76+
$this->order_service->ingestPaymentInfoForRegistrationOrders();
77+
$end = time();
78+
$delta = $end - $start;
79+
$this->info(sprintf("execution call %s seconds", $delta));
80+
81+
82+
} catch (Exception $ex) {
83+
Log::error($ex);
84+
}
85+
}
86+
87+
88+
89+
}

app/Console/Kernel.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class Kernel extends ConsoleKernel
5050
\App\Console\Commands\CreateTestDBCommand::class,
5151
\App\Console\Commands\SeedTestDataCommand::class,
5252
\App\Console\Commands\PublishStreamUpdatesCommand::class,
53-
\App\Console\Commands\PurgeSummitsMarkAsDeletedCommand::class
53+
\App\Console\Commands\PurgeSummitsMarkAsDeletedCommand::class,
54+
\App\Console\Commands\IngestSummitOrderPaymentInfoCommand::class,
5455
];
5556

5657
/**
@@ -105,5 +106,9 @@ protected function schedule(Schedule $schedule)
105106

106107
$schedule->command('summit:purge-mark-as-deleted')->everyTwoHours()->withoutOverlapping()->onOneServer();
107108

109+
// ingest missing payment info
110+
111+
$schedule->command('summit:registration-orders-payment-info-ingest')->everySixHours()->withoutOverlapping()->onOneServer();
112+
108113
}
109114
}

app/Jobs/Emails/IMailTemplatesConstants.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ interface IMailTemplatesConstants
8686
const order_purchase_date= 'order_purchase_date';
8787
const order_credit_card_type = 'order_credit_card_type';
8888
const order_credit_card_4number = 'order_credit_card_4number';
89+
const order_payment_info_type = 'order_payment_info_type';
90+
const order_payment_info_details = 'order_payment_info_details';
8991
const order_currency = 'order_currency';
9092
const order_currency_symbol = 'order_currency_symbol';
9193
const order_discount = 'order_discount';

app/Jobs/Emails/Registration/RegisteredMemberOrderPaidMail.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,12 @@ public function __construct(SummitOrder $order)
5757
$payload[IMailTemplatesConstants::order_number] = $order->getNumber();
5858
$payload[IMailTemplatesConstants::order_qr_value] = $order->getQRCode();
5959
$payload[IMailTemplatesConstants::order_purchase_date] = FormatUtils::getNiceDateMonthDayYearTextual($summit->convertDateFromUTC2TimeZone($order->getCreatedUTC()));
60+
61+
// payment details
6062
$payload[IMailTemplatesConstants::order_credit_card_type] = $order->getCreditCardType();
6163
$payload[IMailTemplatesConstants::order_credit_card_4number] = $order->getCreditCard4Number();
64+
$payload[IMailTemplatesConstants::order_payment_info_type] = $order->getPaymentInfoType();
65+
$payload[IMailTemplatesConstants::order_payment_info_details] = $order->getPaymentInfoDetails();
6266

6367
$summit_reassign_ticket_till_date = $summit->getReassignTicketTillDateLocal();
6468
if(!is_null($summit_reassign_ticket_till_date)) {
@@ -133,6 +137,8 @@ public static function getEmailTemplateSchema(): array{
133137
$payload[IMailTemplatesConstants::order_credit_card_type]['type'] = 'string';
134138
$payload[IMailTemplatesConstants::order_purchase_date]['type'] = 'string';
135139
$payload[IMailTemplatesConstants::order_credit_card_4number]['type'] = 'string';
140+
$payload[IMailTemplatesConstants::order_payment_info_type]['type'] = 'string';
141+
$payload[IMailTemplatesConstants::order_payment_info_details]['type'] = 'array';
136142
$payload[IMailTemplatesConstants::order_currency]['type'] = 'string';
137143
$payload[IMailTemplatesConstants::order_currency_symbol]['type'] = 'string';
138144
$payload[IMailTemplatesConstants::order_raw_amount]['type'] = 'string';

app/ModelSerializers/Summit/Registration/SummitOrderReservationSerializer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class SummitOrderReservationSerializer extends SummitOrderBaseSerializer
3939
'TotalRefundedAmountInCents' => 'total_refunded_amount_in_cents:json_int',
4040
'CreditCardType' => 'credit_card_type:json_string',
4141
'CreditCard4Number' => 'credit_card_4number:json_string',
42+
'PaymentInfoType' => 'payment_info_type:json_string',
43+
'PaymentInfoDetails' => 'payment_info_details:json_string',
4244
];
4345

4446
protected static $allowed_relations = [

app/Models/Foundation/Summit/Registration/SummitOrder.php

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use App\Events\PaymentSummitRegistrationOrderConfirmed;
1616
use App\libs\Utils\PunnyCodeHelper;
1717
use App\Models\Utils\Traits\FinancialTrait;
18+
use App\Services\Apis\IPaymentGatewayAPI;
1819
use Doctrine\Common\Collections\Criteria;
1920
use Illuminate\Support\Facades\Config;
2021
use Illuminate\Support\Facades\Event;
@@ -26,6 +27,7 @@
2627
use models\utils\SilverstripeBaseModel;
2728
use Doctrine\Common\Collections\ArrayCollection;
2829
use Doctrine\ORM\Mapping as ORM;
30+
use function Psy\debug;
2931

3032
/**
3133
* @package models\summit
@@ -214,6 +216,19 @@ class SummitOrder extends SilverstripeBaseModel implements IQREntity
214216
#[ORM\Column(name: 'CreditCard4Numbers', type: 'string')]
215217
private $credit_card_4numbers;
216218

219+
/**
220+
* @var string
221+
*/
222+
#[ORM\Column(name: 'PaymentInfoType', type: 'string')]
223+
private $payment_info_type;
224+
225+
/**
226+
* @var array
227+
*/
228+
#[ORM\Column(name: 'PaymentInfoDetails', type: 'json')]
229+
private $payment_info_details;
230+
231+
217232
/**
218233
* SummitOrder constructor.
219234
*/
@@ -224,6 +239,8 @@ public function __construct()
224239
$this->extra_question_answers = new ArrayCollection();
225240
$this->status = IOrderConstants::ReservedStatus;
226241
$this->payment_method = IOrderConstants::OnlinePaymentMethod;
242+
$this->payment_info_details = [];
243+
$this->payment_info_type = null;
227244
}
228245

229246
public function setPaymentMethodOffline()
@@ -304,13 +321,17 @@ public function getStatus(): string
304321
return $this->status;
305322
}
306323

307-
public function setPaidStatus()
324+
public function setPaidStatus():void
308325
{
309326
$this->status = IOrderConstants::PaidStatus;
310327
$this->approved_payment_date = new \DateTime('now', new \DateTimeZone('UTC'));
311328
}
312329

313-
public function setPaid(array $payload = null)
330+
/**
331+
* @param array|null $payload
332+
* @return void
333+
*/
334+
public function setPaid(array $payload = null):void
314335
{
315336
Log::debug(sprintf("SummitOrder::setPaid order %s", $this->id));
316337
if ($this->isPaid()) {
@@ -324,21 +345,7 @@ public function setPaid(array $payload = null)
324345
$ticket->setPaid();
325346
}
326347

327-
if (!is_null($payload) && isset($payload['order_credit_card_type']) && isset($payload['order_credit_card_4numbers'])) {
328-
329-
Log::debug
330-
(
331-
sprintf
332-
(
333-
"SummitOrder::setPaid order %s setting credit card info %s",
334-
$this->id,
335-
json_encode($payload)
336-
)
337-
);
338-
339-
$this->credit_card_type = $payload['order_credit_card_type'];
340-
$this->credit_card_4numbers = $payload['order_credit_card_4numbers'];
341-
}
348+
$this->setPaymentInfo($payload);
342349

343350
Event::dispatch(new PaymentSummitRegistrationOrderConfirmed($this->getId()));
344351
}
@@ -1245,4 +1252,43 @@ public function getCreditCard4Number():?string
12451252
{
12461253
return $this->credit_card_4numbers;
12471254
}
1255+
1256+
public function getPaymentInfoType(): ?string
1257+
{
1258+
return $this->payment_info_type;
1259+
}
1260+
1261+
1262+
public function getPaymentInfoDetails(): ?array
1263+
{
1264+
return $this->payment_info_details;
1265+
}
1266+
1267+
/**
1268+
* @param array|null $payment_info
1269+
* @return void
1270+
*/
1271+
public function setPaymentInfo(array $payment_info = null): void{
1272+
if (!is_null($payment_info) && isset($payment_info[IPaymentGatewayAPI::PaymentInfo])) {
1273+
1274+
Log::debug
1275+
(
1276+
sprintf
1277+
(
1278+
"SummitOrder::setPaymentInfo order %s setting payment info %s",
1279+
$this->id,
1280+
json_encode($payment_info)
1281+
)
1282+
);
1283+
1284+
$this->payment_info_type = $payment_info[IPaymentGatewayAPI::PaymentInfo][IPaymentGatewayAPI::PaymentInfo_Type] ?? null;
1285+
$this->payment_info_details = $payment_info[IPaymentGatewayAPI::PaymentInfo][IPaymentGatewayAPI::PaymentInfo_Details] ?? [];
1286+
1287+
if($this->payment_info_type === IPaymentGatewayAPI::PaymentInfo_Type_Card){
1288+
// back compat
1289+
$this->credit_card_type = $this->payment_info_details[IPaymentGatewayAPI::PaymentInfo_Type_Card_Brand] ?? null;
1290+
$this->credit_card_4numbers = $this->payment_info_details[IPaymentGatewayAPI::PaymentInfo_Type_Card_Last4] ?? null;
1291+
}
1292+
}
1293+
}
12481294
}

app/Models/Foundation/Summit/Repositories/ISummitOrderRepository.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,12 @@ public function getAllOrderIdsThatNeedsEmailActionReminder(Summit $summit, Pagin
9393
* @throws \Doctrine\DBAL\Driver\Exception
9494
*/
9595
public function deleteAllBySummit(int $summit_id):bool;
96+
97+
/**
98+
* @param Summit $summit
99+
* @param PagingInfo $paging_info
100+
* @return array
101+
*/
102+
public function getAllOrderIdsThatNeedsPaymentInfo(Summit $summit, PagingInfo $paging_info):array;
103+
96104
}

app/Repositories/Summit/DoctrineSummitOrderRepository.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,32 @@ public function getAllOrderIdsThatNeedsEmailActionReminder(Summit $summit, Pagin
431431
$res = $query->getQuery()->getArrayResult();
432432
return array_column($res, 'id');
433433
}
434+
435+
/**
436+
* @param Summit $summit
437+
* @param PagingInfo $paging_info
438+
* @return array
439+
*/
440+
public function getAllOrderIdsThatNeedsPaymentInfo(Summit $summit, PagingInfo $paging_info): array
441+
{
442+
$query = $this->getEntityManager()
443+
->createQueryBuilder()
444+
->distinct(true)
445+
->select("e.id")
446+
->from($this->getBaseEntity(), "e")
447+
->join("e.summit","s")
448+
->where('e.status = :order_status')
449+
->andWhere('s.id = :summit_id')
450+
->andWhere("e.payment_info_type is null");
451+
452+
$query->setParameter("order_status", IOrderConstants::PaidStatus);
453+
$query->setParameter("summit_id", $summit->getId());
454+
455+
$query= $query
456+
->setFirstResult($paging_info->getOffset())
457+
->setMaxResults($paging_info->getPerPage());
458+
459+
$res = $query->getQuery()->getArrayResult();
460+
return array_column($res, 'id');
461+
}
434462
}

app/Services/Apis/IPaymentGatewayAPI.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ class CartAlreadyPaidException extends Exception {
2929
*/
3030
interface IPaymentGatewayAPI
3131
{
32+
public const string PaymentInfo = 'payment_info';
33+
public const string PaymentInfo_Type = 'type';
34+
35+
public const string PaymentInfo_Details = 'details';
36+
37+
public const string PaymentInfo_Type_Card = 'card';
38+
39+
public const string PaymentInfo_Type_Card_Brand = 'brand';
40+
public const string PaymentInfo_Type_Card_Last4 = 'last4';
41+
public const string PaymentInfo_Type_ACH = 'us_bank_account';
42+
43+
public const string PaymentInfo_Type_AliPay = 'alipay';
44+
45+
public const string PaymentInfo_Type_Link = 'link';
46+
3247
/**
3348
* @param SummitOrder $order
3449
* @throws ValidationException
@@ -100,12 +115,7 @@ public function getCartStatus(string $cart_id):?string;
100115
* @param string $cart_id
101116
* @return array|null
102117
*/
103-
public function getCartCreditCardInfo(string $cart_id):?array;
104-
/**
105-
* @param array $payload
106-
* @return array
107-
*/
108-
public function getCreditCardInfo(array $payload): array;
118+
public function getPaymentDetailsInfo(string $cart_id):?array;
109119

110120
/**
111121
* @param string $status

app/Services/Apis/PaymentGateways/LawPayApi.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -539,12 +539,8 @@ public function clearWebHooks():void{
539539
}
540540
}
541541

542-
public function getCreditCardInfo(array $payload): array
543-
{
544-
return [];
545-
}
546542

547-
public function getCartCreditCardInfo(string $cart_id): ?array
543+
public function getPaymentDetailsInfo(string $cart_id): ?array
548544
{
549545
return [];
550546
}

0 commit comments

Comments
 (0)