forked from SeungpilPark/uEngine-bill
-
Notifications
You must be signed in to change notification settings - Fork 7
인보이스 생성 및 발송 설계서
SeungpilPark edited this page Mar 20, 2017
·
1 revision
이메일 발송이 일어나는 상황인, INVOICE_NOTIFICATION,INVOICE_PAYMENT_SUCCESS,INVOICE_PAYMENT_FAILED,SUBSCRIPTION_CANCEL 이벤트를 캐치하는 코드를 제작한다.
@Override
public void handleKillbillEvent(final ExtBusEvent killbillEvent) {
if (!EVENTS_TO_CONSIDER.contains(killbillEvent.getEventType())) {
return;
}
// TODO see https://github.com/killbill/killbill-platform/issues/5
final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
try {
final Account account = osgiKillbillAPI.getAccountUserApi().getAccountById(killbillEvent.getAccountId(), new EmailNotificationContext(killbillEvent.getTenantId()));
final String to = account.getEmail();
if (to == null) {
logService.log(LogService.LOG_INFO, "Account " + account.getId() + " does not have an email address configured, skip...");
return;
}
final EmailNotificationContext context = new EmailNotificationContext(killbillEvent.getTenantId());
switch (killbillEvent.getEventType()) {
case INVOICE_NOTIFICATION:
sendEmailForUpComingInvoice(account, killbillEvent, context);
break;
case INVOICE_PAYMENT_SUCCESS:
case INVOICE_PAYMENT_FAILED:
sendEmailForPayment(account, killbillEvent, context);
break;
case SUBSCRIPTION_CANCEL:
sendEmailForCancelledSubscription(account, killbillEvent, context);
break;
default:
break;
}
logService.log(LogService.LOG_INFO, String.format("Received event %s for object type = %s, id = %s",
killbillEvent.getEventType(), killbillEvent.getObjectType(), killbillEvent.getObjectId()));
} catch (final AccountApiException e) {
logService.log(LogService.LOG_WARNING, String.format("Unable to find account: %s", killbillEvent.getAccountId()), e);
} catch (InvoiceApiException e) {
logService.log(LogService.LOG_WARNING, String.format("Fail to retrieve invoice for account %s", killbillEvent.getAccountId()), e);
} catch (SubscriptionApiException e) {
logService.log(LogService.LOG_WARNING, String.format("Fail to retrieve subscription for account %s", killbillEvent.getAccountId()), e);
} catch (PaymentApiException e) {
logService.log(LogService.LOG_WARNING, String.format("Fail to send email for account %s", killbillEvent.getAccountId()), e);
} catch (EmailException e) {
logService.log(LogService.LOG_WARNING, String.format("Fail to send email for account %s", killbillEvent.getAccountId()), e);
} catch (IOException e) {
logService.log(LogService.LOG_WARNING, String.format("Fail to send email for account %s", killbillEvent.getAccountId()), e);
} catch (TenantApiException e) {
logService.log(LogService.LOG_WARNING, String.format("Fail to send email for account %s", killbillEvent.getAccountId()), e);
} catch (IllegalArgumentException e) {
logService.log(LogService.LOG_WARNING, e.getMessage(), e);
} catch (MustacheException e) {
logService.log(LogService.LOG_WARNING, e.getMessage(), e);
} finally {
Thread.currentThread().setContextClassLoader(previousClassLoader);
}
}
private void sendEmailForUpComingInvoice(final Account account, final ExtBusEvent killbillEvent, final TenantContext context) throws IOException, InvoiceApiException, EmailException, TenantApiException {
Preconditions.checkArgument(killbillEvent.getEventType() == ExtBusEventType.INVOICE_NOTIFICATION, String.format("Unexpected event %s", killbillEvent.getEventType()));
final String dryRunTimePropValue = configProperties.getString(INVOICE_DRY_RUN_TIME_PROPERTY);
Preconditions.checkArgument(dryRunTimePropValue != null, String.format("Cannot find property %s", INVOICE_DRY_RUN_TIME_PROPERTY));
final TimeSpan span = new TimeSpan(dryRunTimePropValue);
final DateTime now = clock.getClock().getUTCNow();
final DateTime targetDateTime = now.plus(span.getMillis());
final PluginCallContext callContext = new PluginCallContext(EmailNotificationActivator.PLUGIN_NAME, now, context.getTenantId());
final Invoice invoice = osgiKillbillAPI.getInvoiceUserApi().triggerInvoiceGeneration(account.getId(), new LocalDate(targetDateTime, account.getTimeZone()), NULL_DRY_RUN_ARGUMENTS, callContext);
if (invoice != null) {
final EmailContent emailContent = templateRenderer.generateEmailForUpComingInvoice(account, invoice, context);
sendEmail(account, emailContent, context);
}
}
private void sendEmailForPayment(final Account account, final ExtBusEvent killbillEvent, final TenantContext context) throws InvoiceApiException, IOException, EmailException, PaymentApiException, TenantApiException {
final UUID invoiceId = killbillEvent.getObjectId();
if (invoiceId == null) {
return;
}
Preconditions.checkArgument(killbillEvent.getEventType() == ExtBusEventType.INVOICE_PAYMENT_FAILED || killbillEvent.getEventType() == ExtBusEventType.INVOICE_PAYMENT_SUCCESS, String.format("Unexpected event %s", killbillEvent.getEventType()));
final Invoice invoice = osgiKillbillAPI.getInvoiceUserApi().getInvoice(invoiceId, context);
if (invoice.getNumberOfPayments() == 0) {
// Aborted payment? Maybe no default payment method...
return;
}
final InvoicePayment invoicePayment = invoice.getPayments().get(invoice.getNumberOfPayments() - 1);
final Payment payment = osgiKillbillAPI.getPaymentApi().getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), context);
final PaymentTransaction lastTransaction = payment.getTransactions().get(payment.getTransactions().size() - 1);
if (lastTransaction.getTransactionType() != TransactionType.PURCHASE &&
lastTransaction.getTransactionType() != TransactionType.REFUND) {
// Ignore for now, but this is easy to add...
return;
}
EmailContent emailContent = null;
if (lastTransaction.getTransactionType() == TransactionType.REFUND && lastTransaction.getTransactionStatus() == TransactionStatus.SUCCESS) {
emailContent = templateRenderer.generateEmailForPaymentRefund(account, lastTransaction, context);
} else {
if (lastTransaction.getTransactionType() == TransactionType.PURCHASE && lastTransaction.getTransactionStatus() == TransactionStatus.SUCCESS) {
emailContent = templateRenderer.generateEmailForSuccessfulPayment(account, invoice, context);
} else if (lastTransaction.getTransactionType() == TransactionType.PURCHASE && lastTransaction.getTransactionStatus() == TransactionStatus.PAYMENT_FAILURE) {
emailContent = templateRenderer.generateEmailForFailedPayment(account, invoice, context);
}
}
if (emailContent != null) {
sendEmail(account, emailContent, context);
}
}
private void sendEmailForCancelledSubscription(final Account account, final ExtBusEvent killbillEvent, final TenantContext context) throws SubscriptionApiException, IOException, EmailException, TenantApiException {
Preconditions.checkArgument(killbillEvent.getEventType() == ExtBusEventType.SUBSCRIPTION_CANCEL, String.format("Unexpected event %s", killbillEvent.getEventType()));
final UUID subscriptionId = killbillEvent.getObjectId();
final Subscription subscription = osgiKillbillAPI.getSubscriptionApi().getSubscriptionForEntitlementId(subscriptionId, context);
if (subscription != null) {
final EmailContent emailContent = subscription.getState() == Entitlement.EntitlementState.CANCELLED ?
templateRenderer.generateEmailForSubscriptionCancellationEffective(account, subscription, context) :
templateRenderer.generateEmailForSubscriptionCancellationRequested(account, subscription, context);
sendEmail(account, emailContent, context);
}
}
private EmailContent getEmailContent(final TemplateType templateType, final AccountData account, @Nullable Subscription subscription, @Nullable final Invoice invoice, @Nullable final PaymentTransaction paymentTransaction, final TenantContext context) throws IOException, TenantApiException {
final String accountLocale = Strings.emptyToNull(account.getLocale());
final Locale locale = accountLocale == null ? Locale.getDefault() : LocaleUtils.toLocale(accountLocale);
final Map<String, Object> data = new HashMap<String, Object>();
final Map<String, String> text = getTranslationMap(accountLocale, ResourceBundleFactory.ResourceBundleType.TEMPLATE_TRANSLATION, context);
data.put("text", text);
data.put("account", account);
if (subscription != null) {
data.put("subscription", subscription);
}
if (invoice != null) {
final InvoiceFormatter formattedInvoice = new DefaultInvoiceFormatter(text, invoice, locale);
data.put("invoice", formattedInvoice);
}
if (paymentTransaction != null) {
final PaymentFormatter formattedPayment = new PaymentFormatter(paymentTransaction, locale);
data.put("payment", formattedPayment);
}
final String templateText = getTemplateText(locale, templateType, context);
final String body = templateEngine.executeTemplateText(templateText, data);
final String subject = new StringBuffer((String) text.get("merchantName")).append(": ").append(text.get(templateType.getSubjectKeyName())).toString();
return new EmailContent(subject, body);
}