2022-03-13 18:05:16 +08:00
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react" ;
2022-07-10 15:45:55 +08:00
import { Button , Result , Spin } from "antd" ;
2022-03-13 18:05:16 +08:00
import * as PaymentBackend from "./backend/PaymentBackend" ;
2023-08-24 23:20:50 +08:00
import * as PricingBackend from "./backend/PricingBackend" ;
import * as SubscriptionBackend from "./backend/SubscriptionBackend" ;
2022-03-13 18:05:16 +08:00
import * as Setting from "./Setting" ;
import i18next from "i18next" ;
class PaymentResultPage extends React . Component {
constructor ( props ) {
super ( props ) ;
2023-08-24 23:20:50 +08:00
const params = new URLSearchParams ( window . location . search ) ;
2022-03-13 18:05:16 +08:00
this . state = {
classes : props ,
2023-08-24 23:20:50 +08:00
owner : props . match ? . params ? . organizationName ? ? props . match ? . params ? . owner ? ? null ,
paymentName : props . match ? . params ? . paymentName ? ? null ,
pricingName : props . pricingName ? ? props . match ? . params ? . pricingName ? ? null ,
subscriptionName : params . get ( "subscription" ) ,
2022-03-13 18:05:16 +08:00
payment : null ,
2023-08-24 23:20:50 +08:00
pricing : props . pricing ? ? null ,
subscription : props . subscription ? ? null ,
2023-06-13 02:00:52 +08:00
timeout : null ,
2022-03-13 18:05:16 +08:00
} ;
}
UNSAFE _componentWillMount ( ) {
this . getPayment ( ) ;
}
2023-06-13 02:00:52 +08:00
componentWillUnmount ( ) {
if ( this . state . timeout !== null ) {
clearTimeout ( this . state . timeout ) ;
}
}
2023-08-24 23:20:50 +08:00
setStateAsync ( state ) {
return new Promise ( ( resolve , reject ) => {
this . setState ( state , ( ) => {
resolve ( ) ;
} ) ;
} ) ;
}
onUpdatePricing ( pricing ) {
this . props . onUpdatePricing ( pricing ) ;
}
async getPayment ( ) {
if ( ! ( this . state . owner && ( this . state . paymentName || ( this . state . pricingName && this . state . subscriptionName ) ) ) ) {
return ;
}
try {
// loading price & subscription
if ( this . state . pricingName && this . state . subscriptionName ) {
if ( ! this . state . pricing ) {
const res = await PricingBackend . getPricing ( this . state . owner , this . state . pricingName ) ;
if ( res . status !== "ok" ) {
throw new Error ( res . msg ) ;
}
const pricing = res . data ;
await this . setStateAsync ( {
pricing : pricing ,
} ) ;
}
if ( ! this . state . subscription ) {
const res = await SubscriptionBackend . getSubscription ( this . state . owner , this . state . subscriptionName ) ;
if ( res . status !== "ok" ) {
throw new Error ( res . msg ) ;
2023-07-30 11:54:42 +08:00
}
2023-08-24 23:20:50 +08:00
const subscription = res . data ;
await this . setStateAsync ( {
subscription : subscription ,
} ) ;
2022-03-13 18:05:16 +08:00
}
2023-08-24 23:20:50 +08:00
const paymentName = this . state . subscription . payment ;
await this . setStateAsync ( {
paymentName : paymentName ,
} ) ;
this . onUpdatePricing ( this . state . pricing ) ;
}
const res = await PaymentBackend . getPayment ( this . state . owner , this . state . paymentName ) ;
if ( res . status !== "ok" ) {
throw new Error ( res . msg ) ;
}
const payment = res . data ;
await this . setStateAsync ( {
payment : payment ,
2022-03-13 18:05:16 +08:00
} ) ;
2023-08-24 23:20:50 +08:00
if ( payment . state === "Created" ) {
2023-09-13 17:30:51 +08:00
if ( [ "PayPal" , "Stripe" , "Alipay" ] . includes ( payment . type ) ) {
2023-08-24 23:20:50 +08:00
this . setState ( {
timeout : setTimeout ( async ( ) => {
await PaymentBackend . notifyPayment ( this . state . owner , this . state . paymentName ) ;
this . getPayment ( ) ;
} , 1000 ) ,
} ) ;
} else {
this . setState ( {
timeout : setTimeout ( ( ) => this . getPayment ( ) , 1000 ) ,
} ) ;
}
}
} catch ( err ) {
Setting . showMessage ( "error" , err . message ) ;
return ;
}
2022-03-13 18:05:16 +08:00
}
2023-07-30 11:54:42 +08:00
goToPaymentUrl ( payment ) {
if ( payment . returnUrl === undefined || payment . returnUrl === null || payment . returnUrl === "" ) {
Setting . goToLink ( ` ${ window . location . origin } /products/ ${ payment . owner } / ${ payment . productName } /buy ` ) ;
} else {
Setting . goToLink ( payment . returnUrl ) ;
}
}
2022-03-13 18:05:16 +08:00
render ( ) {
const payment = this . state . payment ;
if ( payment === null ) {
return null ;
}
if ( payment . state === "Paid" ) {
return (
2023-08-24 23:20:50 +08:00
< div className = "login-content" >
2022-03-13 18:05:16 +08:00
{
Setting . renderHelmet ( payment )
}
< Result
status = "success"
2022-03-14 02:07:55 +08:00
title = { ` ${ i18next . t ( "payment:You have successfully completed the payment" ) } : ${ payment . productDisplayName } ` }
2022-03-13 18:05:16 +08:00
subTitle = { i18next . t ( "payment:Please click the below button to return to the original website" ) }
extra = { [
< Button type = "primary" key = "returnUrl" onClick = { ( ) => {
2023-07-30 11:54:42 +08:00
this . goToPaymentUrl ( payment ) ;
2022-03-13 18:05:16 +08:00
} } >
{ i18next . t ( "payment:Return to Website" ) }
2022-08-06 23:54:56 +08:00
< / B u t t o n > ,
2022-03-13 18:05:16 +08:00
] }
/ >
< / d i v >
2022-07-10 15:45:55 +08:00
) ;
2022-03-13 18:05:16 +08:00
} else if ( payment . state === "Created" ) {
return (
2023-08-24 23:20:50 +08:00
< div className = "login-content" >
2022-03-13 18:05:16 +08:00
{
Setting . renderHelmet ( payment )
}
< Result
status = "info"
2022-03-14 02:07:55 +08:00
title = { ` ${ i18next . t ( "payment:The payment is still under processing" ) } : ${ payment . productDisplayName } , ${ i18next . t ( "payment:the current state is" ) } : ${ payment . state } , ${ i18next . t ( "payment:please wait for a few seconds..." ) } ` }
2022-03-13 18:05:16 +08:00
subTitle = { i18next . t ( "payment:Please click the below button to return to the original website" ) }
extra = { [
2022-08-09 12:19:56 +08:00
< Spin key = "returnUrl" size = "large" tip = { i18next . t ( "payment:Processing..." ) } / > ,
2022-03-13 18:05:16 +08:00
] }
/ >
< / d i v >
2022-07-10 15:45:55 +08:00
) ;
2023-07-31 15:24:13 +08:00
} else if ( payment . state === "Canceled" ) {
return (
2023-08-24 23:20:50 +08:00
< div className = "login-content" >
2023-07-31 15:24:13 +08:00
{
Setting . renderHelmet ( payment )
}
< Result
status = "warning"
title = { ` ${ i18next . t ( "payment:The payment has been canceled" ) } : ${ payment . productDisplayName } , ${ i18next . t ( "payment:the current state is" ) } : ${ payment . state } ` }
subTitle = { i18next . t ( "payment:Please click the below button to return to the original website" ) }
extra = { [
2023-08-15 00:16:30 +08:00
< Button type = "primary" key = "returnUrl" onClick = { ( ) => {
this . goToPaymentUrl ( payment ) ;
} } >
{ i18next . t ( "payment:Return to Website" ) }
< / B u t t o n > ,
] }
/ >
< / d i v >
) ;
} else if ( payment . state === "Timeout" ) {
return (
2023-08-24 23:20:50 +08:00
< div className = "login-content" >
2023-08-15 00:16:30 +08:00
{
Setting . renderHelmet ( payment )
}
< Result
status = "warning"
title = { ` ${ i18next . t ( "payment:The payment has time out" ) } : ${ payment . productDisplayName } , ${ i18next . t ( "payment:the current state is" ) } : ${ payment . state } ` }
subTitle = { i18next . t ( "payment:Please click the below button to return to the original website" ) }
extra = { [
2023-07-31 15:24:13 +08:00
< Button type = "primary" key = "returnUrl" onClick = { ( ) => {
this . goToPaymentUrl ( payment ) ;
} } >
{ i18next . t ( "payment:Return to Website" ) }
< / B u t t o n > ,
] }
/ >
< / d i v >
) ;
2022-03-13 18:05:16 +08:00
} else {
return (
2023-08-24 23:20:50 +08:00
< div className = "login-content" >
2022-03-13 18:05:16 +08:00
{
Setting . renderHelmet ( payment )
}
< Result
status = "error"
2022-03-14 02:07:55 +08:00
title = { ` ${ i18next . t ( "payment:The payment has failed" ) } : ${ payment . productDisplayName } , ${ i18next . t ( "payment:the current state is" ) } : ${ payment . state } ` }
2023-07-31 15:24:13 +08:00
subTitle = { ` ${ i18next . t ( "payment:Failed reason" ) } : ${ payment . message } ` }
2022-03-13 18:05:16 +08:00
extra = { [
< Button type = "primary" key = "returnUrl" onClick = { ( ) => {
2023-07-30 11:54:42 +08:00
this . goToPaymentUrl ( payment ) ;
2022-03-13 18:05:16 +08:00
} } >
{ i18next . t ( "payment:Return to Website" ) }
2022-08-06 23:54:56 +08:00
< / B u t t o n > ,
2022-03-13 18:05:16 +08:00
] }
/ >
< / d i v >
2022-07-10 15:45:55 +08:00
) ;
2022-03-13 18:05:16 +08:00
}
}
}
export default PaymentResultPage ;