Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
nestjs-braintree
Advanced tools
A module for Braintree reoccurring payments and transactions built for the Nestjs framework.
Using the Braintree node SDK.
NOTE! Currently building
$ yarn add nestjs-braintree
import { Module } from '@nestjs/common';
import { BraintreeModule } from 'nestjs-braintree';
import * as braintree from 'braintree';
@Module({
imports: [
BraintreeModule.forRoot({
environment: braintree.Environment.Sandbox,
merchantId: '',
publicKey: '',
privateKey: '',
}),
],
})
export default class AppModule {}
import { Module } from '@nestjs/common';
import { BraintreeModule } from 'nestjs-braintree';
@Module({
imports: [
BraintreeModule.forFeature(),
],
})
export default class SubModule {}
import { Module } from '@nestjs/common';
import { BraintreeModule } from 'nestjs-braintree';
import { ConfigModule, ConfigService } from 'nestjs-config';
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRootAsync({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
],
})
export default class AppModule {}
//config/braintree.ts
import * as braintree from 'braintree';
export default {
environment:
process.env.NODE_ENV == 'development'
? braintree.Environment.Sandbox
: braintree.Environment.Live,
merchantId: process.env.BRAINTREE_MERCHANT_ID,
publicKey: process.env.BRAINTREE_PUBLIC_KEY,
privateKey: process.env.BRAINTREE_PRIVATE_KEY,
};
Braintree is capable of making one off transactions
import { Module } from '@nestjs/common';
import { BraintreeModule, InjectBraintreeProvider } from 'nestjs-braintree';
import { ConfigModule, ConfigService } from 'nestjs-config';
class TransactionProvider {
constructor(
@InjectBraintreeProvider()
private readonly braintreeProvider: BraintreeProvider,
) {}
takePayment(amount: string, nonce: string) {
this.braintreeProvider.sale({
payment_method_nonce: nonce,
amount,
});
}
}
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRoot({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
],
providers: [TransactionProvider],
})
export default class AppModule {}
Avaliable methods relating to transactions are
braintreeProvider.sale(transaction: BraintreeTransactionInterface): Promise<BraintreeTransactionResultInterface>
braintreeProvider.refund(transactionId: string, amount?: string, orderId?: string): Promise<BraintreeTransactionResultInterface>
braintreeProvider.find(transactionId: string): Promise<BraintreeTransactionResultInterface>
The braintree SDK does offer additional methods. I will implement them soon hopefully
When using subscriptions with braintree, braintree will issue webhooks to your endpoint which you can use the decorators to handle those actions.
import { Module } from '@nestjs/common';
import {
BraintreeModule,
BraintreeWebhookModule,
BraintreeSubscriptionCanceled,
BraintreeSubscriptionExpired,
BraintreeWebhookHandler,
} from 'nestjs-braintree';
import { ConfigModule, ConfigService } from 'nestjs-config';
@BraintreeWebhookHandler()
class SubscriptionProvider {
@BraintreeSubscriptionCanceled()
canceled() {
console.log('subscription canceled');
}
@BraintreeSubscriptionExpired()
expired() {
console.log('subscription expired');
}
}
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRootAsync({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
BraintreeWebhookModule,
],
providers: [SubscriptionProvider],
})
export default class AppModule {}
The idea of the Braintree Webhook Module is to make implementation of actions a lot easier. For example we can build a provider like this one to cancel canceled subscriptions.
@BraintreeWebhookHandler()
export class SubscriptionProvider {
constructor(@InjectRepository(Subscription) private readonly subscriptionRepository: Repository<Subscription>) {}
async findByBraintreeId(braintreeId: string): Promise<Subscription|null> {
return await this.subscriptionRepository.find({
where: {
braintreeId,
},
});
}
async update(subscription: Subscription): Promise<boolean> {
return await this.subscriptionRepository.update(subscription);
}
@BraintreeSubscriptionCanceled()
async canceled(webhook: BraintreeWebhook) {
const subscription = await this.findByBraintreeId(webhook.subscription.id);
if (!subscription) {
return;
}
subscription.active = false;
await this.update(subscription);
}
}
Shortname | Braintree webhook name/const/key | NestJS decorator |
---|---|---|
Subscription Canceled | subscription_canceled | @BraintreeSubscriptionCanceled() |
Subscription Expired | subscription_expired | @BraintreeSubscriptionExpired() |
Subscription Charged Successfully | subscription_charged_successfully | @BraintreeSubscriptionChargedSuccessfully() |
Subscription Charged Unsuccessfully | subscription_charged_unsuccessfully | @BraintreeSubscriptionChargedUnsuccessfully() |
Subscription Went Active | subscription_went_active | @BraintreeSubscriptionWentActive() |
Subscription Went Past Due | subscription_went_past_due | @BraintreeSubscriptionWentPastDue() |
Subscription Trial Ended | subscription_trial_ended | @BraintreeSubscriptionTrialEnded() |
You can find out more about the webhooks here.
You may want to divert from the default routing of {your_domain}/braintree/webhook
for whatever reason. You can do so using the forRoot
method on the BraintreeWebhookModule
like so
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRootAsync({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
BraintreeWebhookModule.forRoot({
root: 'replace-braintree',
handle: 'replace-webhook',
}),
],
providers: [SubscriptionProvider],
})
export default class AppModule {}
The above will result in your route for your braintree webhooks being {your_domain}/replace-braintree/replace-webhook
FAQs
Nestjs braintree module
We found that nestjs-braintree demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.