Payment request not found.
} else if (PaymentRequest.State == PaymentRequestState.Completed) {Thank you for your purchase.
} else {The payment was not completed.
} @code { [Parameter] [SupplyParameterFromQuery] public Guid? PaymentRequestId { get; set; } private PaymentRequestWithDetailsDto PaymentRequest { get; set; } protected override async Task OnParametersSetAsync() { PaymentRequest = PaymentRequestId.HasValue ? await PaymentRequestAppService.GetAsync(PaymentRequestId.Value) : null; } } ``` Keep the callback page limited to displaying the current result because users can revisit a callback URL. `PaymentRequestCompletedEto` is published when `IPaymentRequestAppService.CompleteAsync` completes a request, so an idempotent handler can fulfill orders for flows that finish through that application service. It isn't emitted for every direct request-state update; for example, the built-in Stripe webhook can complete a request without publishing this event. If your gateway can complete payments only through a webhook, add an application-owned, idempotent fulfillment or reconciliation path for that trusted webhook flow and verify the persisted payment-request state before granting access. ### Angular UI For Angular applications, you need to read and apply the steps explained in the following sections: #### Configurations Add `providePaymentAdminConfig` from `@volo/abp.ng.payment/admin/config` to the root application configuration. The same example shows the optional remote endpoint entries when the public and admin APIs are hosted separately: ```typescript // app.config.ts import { ApplicationConfig } from '@angular/core'; import { providePaymentAdminConfig } from '@volo/abp.ng.payment/admin/config'; export const appConfig: ApplicationConfig = { providers: [ // ... providePaymentAdminConfig(), ], }; // environment.ts export const environment = { apis: { default: { url: 'https://localhost:44300', }, AbpPaymentCommon: { url: 'https://localhost:44301', }, AbpPaymentAdmin: { url: 'https://localhost:44302', }, }, }; ``` `AbpPaymentCommon` is used by the payment-request proxies and is the server-side remote service name for the gateway endpoints. The currently published Angular gateway proxy, which is used by the public gateway-selection component, sends gateway requests through `AbpPaymentAdmin`; administration proxies also use `AbpPaymentAdmin`. When the APIs are hosted separately, configure both entries and expose `/api/payment/gateways` through the `AbpPaymentAdmin` URL until the client and server remote service names are aligned. Each missing entry independently falls back to `default.url`. Lazy-load both the admin and public payment routes under the `payment` path: ```typescript // app.routes.ts import { Routes } from '@angular/router'; const APP_ROUTES: Routes = [ // ... { path: 'payment', loadChildren: () => Promise.all([ import('@volo/abp.ng.payment/admin').then(c => c.createRoutes()), import('@volo/abp.ng.payment').then(c => c.createRoutes()), ]).then(([adminRoutes, publicRoutes]) => [...adminRoutes, ...publicRoutes]), }, ]; ``` The public route factory adds `gateway-selection`, `:gateway/prepayment`, and `:gateway/post-payment`. The admin route factory adds plans, gateway plans, requests, and payment request products. The public package exposes replaceable component keys through `ePaymentComponents`. Use `registerPrePaymentComponent` or `registerPostPaymentComponent` with `ReplaceableComponentsService` to replace a gateway-specific payment page. The admin `createRoutes` method accepts `PaymentConfigOptions` for entity action, toolbar action, entity property, create form, and edit form contributors on the plans and gateway plans pages. ### Pages #### Public Pages ##### Payment Gateway Selection This page allows selecting a payment gateway. If there is only one payment gateway configured for the application, this page will be skipped.  ##### PrePayment Page Some payment gateways require additional information before redirecting to the payment gateway. For example, PayU and Iyzico require customer information (Name, Surname, Email Address, etc.) before processing the payment.  #### Admin Pages ##### Payment Plans Page Payment plans for subscriptions can be managed on this page. You can connect external subscriptions for each gateway to a plan.   ##### Payment Request List This page lists all the payment request operations in the application.  ## Options ### PaymentOptions `PaymentOptions` is used to store list of payment gateways. You don't have to configure this manually for existing payment gateways. You can, however, add a new gateway like below; Add `using Volo.Abp.Localization;` to the module class file for `FixedLocalizableString`. ````csharp Configure