@@ -17,6 +17,17 @@ import cloudPaymentsApi, { CloudPaymentsJsonData } from '../utils/cloudPaymentsA
1717 */
1818const AMOUNT_FOR_CARD_VALIDATION = 1 ;
1919
20+ /**
21+ * Input data for composePayment query
22+ */
23+ interface ComposePaymentArgs {
24+ input : {
25+ workspaceId : string ;
26+ tariffPlanId : string ;
27+ shouldSaveCard ?: boolean ;
28+ } ;
29+ }
30+
2031/**
2132 * Data for processing payment with saved card
2233 */
@@ -58,6 +69,86 @@ export default {
5869 ) : Promise < BusinessOperationModel [ ] > {
5970 return factories . businessOperationsFactory . getWorkspacesBusinessOperations ( ids ) ;
6071 } ,
72+
73+ /**
74+ * GraphQL version of composePayment: prepares data before charge
75+ */
76+ async composePayment (
77+ _obj : undefined ,
78+ { input } : ComposePaymentArgs ,
79+ { user, factories } : ResolverContextWithUser
80+ ) : Promise < {
81+ invoiceId : string ;
82+ plan : { id : string ; name : string ; monthlyCharge : number } ;
83+ isCardLinkOperation : boolean ;
84+ currency : string ;
85+ checksum : string ;
86+ nextPaymentDate : Date ;
87+ } > {
88+ const { workspaceId, tariffPlanId, shouldSaveCard } = input ;
89+
90+ if ( ! workspaceId || ! tariffPlanId || ! user ?. id ) {
91+ throw new UserInputError ( 'No workspaceId, tariffPlanId or user id provided' ) ;
92+ }
93+
94+ const workspace = await factories . workspacesFactory . findById ( workspaceId ) ;
95+ const plan = await factories . plansFactory . findById ( tariffPlanId ) ;
96+
97+ if ( ! workspace || ! plan ) {
98+ throw new UserInputError ( "Can't get workspace or plan by provided ids" ) ;
99+ }
100+
101+ const member = await workspace . getMemberInfo ( user . id ) ;
102+
103+ if ( ! member ) {
104+ throw new UserInputError ( 'User is not a member of the workspace' ) ;
105+ }
106+
107+ const now = new Date ( ) ;
108+ const invoiceId = `${ workspace . name } ${ now . getDate ( ) } /${ now . getMonth ( ) + 1 } ${ plan . name } ` ;
109+
110+ const isCardLinkOperation = workspace . tariffPlanId . toString ( ) === tariffPlanId && ! workspace . isTariffPlanExpired ( ) ;
111+
112+ // Calculate next payment date
113+ const lastChargeDate = workspace . lastChargeDate ? new Date ( workspace . lastChargeDate ) : now ;
114+ let nextPaymentDate = isCardLinkOperation ? new Date ( lastChargeDate ) : new Date ( now ) ;
115+
116+ if ( workspace . isDebug ) {
117+ nextPaymentDate . setDate ( nextPaymentDate . getDate ( ) + 1 ) ;
118+ } else {
119+ nextPaymentDate . setMonth ( nextPaymentDate . getMonth ( ) + 1 ) ;
120+ }
121+
122+ const checksumData = isCardLinkOperation
123+ ? {
124+ isCardLinkOperation : true as const ,
125+ workspaceId : workspace . _id . toString ( ) ,
126+ userId : user . id ,
127+ nextPaymentDate : nextPaymentDate . toISOString ( ) ,
128+ }
129+ : {
130+ workspaceId : workspace . _id . toString ( ) ,
131+ userId : user . id ,
132+ tariffPlanId : plan . _id . toString ( ) ,
133+ shouldSaveCard : Boolean ( shouldSaveCard ) ,
134+ nextPaymentDate : nextPaymentDate . toISOString ( ) ,
135+ } ;
136+
137+ const checksum = await checksumService . generateChecksum ( checksumData ) ;
138+
139+ return {
140+ invoiceId,
141+ plan : {
142+ id : plan . _id . toString ( ) ,
143+ name : plan . name ,
144+ monthlyCharge : plan . monthlyCharge ,
145+ } ,
146+ isCardLinkOperation,
147+ currency : 'RUB' ,
148+ checksum,
149+ nextPaymentDate,
150+ } ;
151+ } ,
61152 } ,
62153 /**
63154 * Resolver for Union Payload type.
0 commit comments