@@ -39,6 +39,8 @@ public CSCGlobalCAPlugin()
3939
4040 public int SyncFilterDays { get ; set ; }
4141
42+ public int RenewalWindowDays { get ; set ; }
43+
4244 //done
4345 public void Initialize ( IAnyCAPluginConfigProvider configProvider , ICertificateDataReader certificateDataReader )
4446 {
@@ -57,6 +59,15 @@ public void Initialize(IAnyCAPluginConfigProvider configProvider, ICertificateDa
5759 Logger . LogDebug ( $ "SyncFilterDays configured to { SyncFilterDays } days") ;
5860 }
5961 }
62+
63+ RenewalWindowDays = 30 ; // default
64+ if ( configProvider . CAConnectionData . TryGetValue ( Constants . RenewalWindowDays , out var renewalWindowObj ) )
65+ {
66+ if ( int . TryParse ( renewalWindowObj ? . ToString ( ) , out var renewalWindowDays ) && renewalWindowDays > 0 )
67+ RenewalWindowDays = renewalWindowDays ;
68+ }
69+ Logger . LogDebug ( "RenewalWindowDays configured to {Days} days" , RenewalWindowDays ) ;
70+
6071 Logger . MethodExit ( LogLevel . Debug ) ;
6172 }
6273
@@ -252,17 +263,44 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
252263 return _requestManager . GetEnrollmentResult ( enrollmentResponse ) ;
253264 case EnrollmentType . RenewOrReissue :
254265 Logger . LogTrace ( "Entering Renew Enrollment" ) ;
255- //Logic to determine renew vs reissue
256- var renewal = false ;
257266 var order_id = await _certificateDataReader . GetRequestIDBySerialNumber ( priorSn ) ;
258- var expirationDate = _certificateDataReader . GetExpirationDateByRequestId ( order_id ) ;
259- if ( expirationDate == null )
267+
268+ // Determine renew vs reissue based on order expiry window.
269+ // Fetch the live cert record from CSC to get the orderDate, then compute
270+ // orderExpiry = orderDate + 1 year (annual subscription assumption).
271+ // If today falls within RenewalWindowDays of orderExpiry → Renewal (new paid order).
272+ // Otherwise → Reissue (free reissue under the same active order).
273+ var renewal = false ;
274+ try
275+ {
276+ var liveCert = await CscGlobalClient . SubmitGetCertificateAsync ( order_id [ ..36 ] ) ;
277+ if ( liveCert != null && DateTime . TryParse ( liveCert . OrderDate , out var orderDate ) )
278+ {
279+ var orderExpiry = orderDate . AddYears ( 1 ) ;
280+ var daysUntilOrderExpiry = ( orderExpiry - DateTime . UtcNow ) . TotalDays ;
281+ renewal = daysUntilOrderExpiry <= RenewalWindowDays ;
282+ Logger . LogDebug (
283+ "RenewOrReissue: orderDate={OrderDate}, orderExpiry={OrderExpiry}, daysRemaining={Days}, renewalWindow={Window}, isRenewal={IsRenewal}" ,
284+ liveCert . OrderDate , orderExpiry . ToString ( "dd-MMM-yyyy" ) ,
285+ ( int ) daysUntilOrderExpiry , RenewalWindowDays , renewal ) ;
286+ }
287+ else
288+ {
289+ // Fallback: if we can't parse orderDate, use cert expiration as before
290+ var expirationDate = _certificateDataReader . GetExpirationDateByRequestId ( order_id )
291+ ?? ( await GetSingleRecord ( order_id ) ) . RevocationDate ;
292+ renewal = expirationDate < DateTime . Now ;
293+ Logger . LogDebug ( "RenewOrReissue: falling back to cert expiry check, isRenewal={IsRenewal}" , renewal ) ;
294+ }
295+ }
296+ catch ( Exception ex )
260297 {
261- var localcert = await GetSingleRecord ( order_id ) ;
262- expirationDate = localcert . RevocationDate ;
298+ Logger . LogWarning ( "RenewOrReissue: failed to fetch live cert for order decision, falling back to cert expiry. Error: {Error}" , ex . Message ) ;
299+ var expirationDate = _certificateDataReader . GetExpirationDateByRequestId ( order_id )
300+ ?? ( await GetSingleRecord ( order_id ) ) . RevocationDate ;
301+ renewal = expirationDate < DateTime . Now ;
263302 }
264303
265- if ( expirationDate < DateTime . Now ) renewal = true ;
266304 if ( renewal )
267305 {
268306 //One click won't work for this implementation b/c we are missing enrollment params
@@ -401,6 +439,13 @@ public Dictionary<string, PropertyConfigInfo> GetCAConnectorAnnotations()
401439 Hidden = false ,
402440 DefaultValue = "5" ,
403441 Type = "Number"
442+ } ,
443+ [ Constants . RenewalWindowDays ] = new ( )
444+ {
445+ Comments = "Number of days before the annual order expiry within which a RenewOrReissue triggers a paid Renewal rather than a free Reissue. Default is 30." ,
446+ Hidden = false ,
447+ DefaultValue = "30" ,
448+ Type = "Number"
404449 }
405450 } ;
406451 }
0 commit comments