mirror of
https://github.com/HackPlan/RootPanel.git
synced 2026-05-15 13:40:54 +08:00
update INSTALL.md, refactor rpvhost, bitcoin, fixbugs
This commit is contained in:
108
INSTALL.md
108
INSTALL.md
@@ -6,43 +6,15 @@
|
||||
apt-get update
|
||||
apt-get upgrade
|
||||
|
||||
vi /etc/hostname
|
||||
vi /etc/hosts
|
||||
|
||||
apt-get install mongodb=1:2.4.9-1ubuntu2
|
||||
apt-get install python g++ make nodejs git nginx redis-server supervisor
|
||||
|
||||
npm install coffee-script -g
|
||||
|
||||
mongo
|
||||
|
||||
use admin
|
||||
db.addUser({user: 'rpadmin', pwd: 'password', roles: ['readWriteAnyDatabase', 'userAdminAnyDatabase', 'dbAdminAnyDatabase', 'clusterAdmin']})
|
||||
use RootPanel
|
||||
db.addUser({user: 'rpadmin', pwd: 'password', roles: ['readWrite']})
|
||||
|
||||
vi /etc/mongodb.conf
|
||||
|
||||
auth = true
|
||||
noprealloc = true
|
||||
smallfiles = true
|
||||
|
||||
vi /etc/redis/redis.conf
|
||||
|
||||
requirepass password
|
||||
|
||||
rm /etc/nginx/sites-enabled/default
|
||||
|
||||
vi /etc/nginx/sites-enabled/rpadmin
|
||||
|
||||
ssl_certificate /home/rpadmin/rpvhost.crt;
|
||||
ssl_certificate_key /home/rpadmin/keys/rpvhost.key;
|
||||
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:80 default_server ipv6only=on;
|
||||
|
||||
rewrite .* $scheme://rp.rpvhost.net/#redirect redirect;
|
||||
@@ -50,7 +22,6 @@
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl;
|
||||
|
||||
server_name rp.rpvhost.net;
|
||||
|
||||
@@ -67,8 +38,6 @@
|
||||
useradd -m rpadmin
|
||||
usermod -G rpadmin -a www-data
|
||||
|
||||
mkdir -m 750 /home/rpadmin/keys
|
||||
|
||||
vi /etc/sudoers
|
||||
|
||||
rpadmin ALL=(ALL) NOPASSWD: ALL
|
||||
@@ -99,10 +68,70 @@
|
||||
redirect_stderr = true
|
||||
user = rpadmin
|
||||
|
||||
service nginx restart
|
||||
service mongodb restart
|
||||
service redis-server restart
|
||||
service supervisor restart
|
||||
### Optional Security Settings
|
||||
|
||||
mongo
|
||||
|
||||
use admin
|
||||
db.addUser({user: 'rpadmin', pwd: 'password', roles: ['readWriteAnyDatabase', 'userAdminAnyDatabase', 'dbAdminAnyDatabase', 'clusterAdmin']})
|
||||
use RootPanel
|
||||
db.addUser({user: 'rpadmin', pwd: 'password', roles: ['readWrite']})
|
||||
|
||||
vi /etc/mongodb.conf
|
||||
|
||||
auth = true
|
||||
|
||||
vi /etc/redis/redis.conf
|
||||
|
||||
requirepass password
|
||||
|
||||
rm /etc/nginx/sites-enabled/default
|
||||
|
||||
### Optional Performance Settings
|
||||
|
||||
|
||||
vi /etc/hostname
|
||||
vi /etc/hosts
|
||||
|
||||
vi /etc/mongodb.conf
|
||||
|
||||
noprealloc = true
|
||||
smallfiles = true
|
||||
|
||||
### Optional SSL Settings
|
||||
|
||||
vi /etc/nginx/sites-enabled/rpadmin
|
||||
|
||||
ssl_certificate /home/rpadmin/rpvhost.crt;
|
||||
ssl_certificate_key /home/rpadmin/keys/rpvhost.key;
|
||||
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:80 default_server ipv6only=on;
|
||||
|
||||
rewrite .* $scheme://rp.rpvhost.net/#redirect redirect;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl;
|
||||
|
||||
server_name rp.rpvhost.net;
|
||||
|
||||
location ~ /\.git {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass http://unix:/home/rpadmin/rootpanel.sock:/;
|
||||
}
|
||||
}
|
||||
|
||||
mkdir -m 750 /home/rpadmin/keys
|
||||
|
||||
### Clusters
|
||||
|
||||
@@ -111,7 +140,7 @@
|
||||
su rpadmin
|
||||
|
||||
mkdir ~/.ssh
|
||||
echo 'master key' >> ~/.ssh/authorized_keys
|
||||
echo 'Master SSH Public Key' >> ~/.ssh/authorized_keys
|
||||
chmod -R 700 ~/.ssh
|
||||
|
||||
### Plugins
|
||||
@@ -180,3 +209,10 @@
|
||||
|
||||
# Node.js
|
||||
npm install forever gulp mocha harp bower -g
|
||||
|
||||
### Restart Services
|
||||
|
||||
service nginx restart
|
||||
service mongodb restart
|
||||
service redis-server restart
|
||||
service supervisor restart
|
||||
|
||||
@@ -134,6 +134,7 @@ app.express.use app.middleware.accountHelpers
|
||||
app.express.set 'views', path.join(__dirname, 'core/view')
|
||||
app.express.set 'view engine', 'jade'
|
||||
|
||||
app.express.use '/component', require './core/router/component'
|
||||
app.express.use '/account', require './core/router/account'
|
||||
app.express.use '/billing', require './core/router/billing'
|
||||
app.express.use '/ticket', require './core/router/ticket'
|
||||
@@ -144,7 +145,7 @@ app.express.use '/panel', require './core/router/panel'
|
||||
app.i18n.init()
|
||||
app.interfaces.Plan.initPlans()
|
||||
app.interfaces.Node.initNodes()
|
||||
app.pluggable.initPlugins()
|
||||
app.interfaces.Plugin.initPlugins()
|
||||
|
||||
app.express.get '/', (req, res) ->
|
||||
unless res.headerSent
|
||||
|
||||
@@ -3,9 +3,7 @@ getParameterNames = require 'get-parameter-names'
|
||||
CounterCache = require 'counter-cache'
|
||||
_ = require 'underscore'
|
||||
|
||||
config = require '../config'
|
||||
|
||||
{redis} = app
|
||||
{redis, config} = app
|
||||
|
||||
exports.counter = new CounterCache()
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{_, async} = app.libs
|
||||
{logger} = app
|
||||
{Node} = app.interfaces
|
||||
{Account, Component} = app.models
|
||||
|
||||
Node = require './Node'
|
||||
|
||||
module.exports = class ComponentType
|
||||
@component_types = {}
|
||||
|
||||
@@ -19,29 +20,6 @@ module.exports = class ComponentType
|
||||
initialize: (component, callback) ->
|
||||
callback()
|
||||
|
||||
populateComponent: (component) ->
|
||||
if component.toObject
|
||||
component = component.toObject()
|
||||
|
||||
async.parallel
|
||||
account: (callback) ->
|
||||
Account.findById component.account_id, callback
|
||||
|
||||
coworkers: (callback) ->
|
||||
async.each component.coworkers, (coworker, callback) ->
|
||||
Account.findById coworker.account_id, (err, account) ->
|
||||
callback _.extend coworker,
|
||||
account: account
|
||||
, callback
|
||||
|
||||
, (err, result) ->
|
||||
{account, coworkers} = result
|
||||
|
||||
callback _.extend component,
|
||||
account: account
|
||||
coworkers: coworkers
|
||||
physical_node: Node.nodes[component.physical_node]
|
||||
|
||||
# @param callback(err, component)
|
||||
createComponent: (account, info, callback) ->
|
||||
{name, physical_node} = info
|
||||
@@ -54,18 +32,18 @@ module.exports = class ComponentType
|
||||
physical_node: physical_node
|
||||
dependencies: {}
|
||||
, (err, component) =>
|
||||
@populateComponent component, (component) =>
|
||||
@initialize component, (err) =>
|
||||
component.populateComponent (populated_component) =>
|
||||
@initialize populated_component, (err) =>
|
||||
return callback err if err
|
||||
|
||||
Component.markAsStatus component, 'running', callback
|
||||
component.markAsStatus 'running', callback
|
||||
|
||||
# @param callback(err)
|
||||
destroyComponent: (component, callback) ->
|
||||
Component.markAsStatus component, 'destroying', (err) =>
|
||||
component.markAsStatus 'destroying', (err) =>
|
||||
return callback err if err
|
||||
|
||||
@populateComponent component, (component) =>
|
||||
component.populateComponent (component) =>
|
||||
@destroy component, (err) =>
|
||||
return callback err if err
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
{_, child_process, async} = app.libs
|
||||
{config, logger} = app
|
||||
{available_plugins} = config.plugin
|
||||
|
||||
module.exports = class Node
|
||||
info: null
|
||||
name: null
|
||||
@@ -7,15 +11,20 @@ module.exports = class Node
|
||||
|
||||
@initNodes: ->
|
||||
for name, info of config.nodes
|
||||
@nodes[name] = new @constructor _.extend info,
|
||||
@nodes[name] = new Node _.extend info,
|
||||
name: name
|
||||
|
||||
@get: (name) ->
|
||||
return @nodes[name]
|
||||
|
||||
constructor: (@info) ->
|
||||
@name = @info.name
|
||||
@master = true if @info.master
|
||||
_.extend @, info
|
||||
|
||||
for component_type in @available_components
|
||||
unless component_type in available_plugins
|
||||
err = new Error "Node:#{@name} include unknown Component:#{component_type}"
|
||||
logger.fatal err
|
||||
throw err
|
||||
|
||||
# @param callback(err, stdout, stderr)
|
||||
runCommand: (command, callback) ->
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
{_} = app.libs
|
||||
{config, logger} = app
|
||||
|
||||
{available_plugins} = config.plugin
|
||||
|
||||
module.exports = class Plan
|
||||
@plans = {}
|
||||
|
||||
@initPlans: ->
|
||||
for name, info of config.plans
|
||||
@plans[name] = new @constructor _.extend info,
|
||||
@plans[name] = new Plan _.extend info,
|
||||
name: name
|
||||
|
||||
@get: (name) ->
|
||||
@@ -13,6 +18,11 @@ module.exports = class Plan
|
||||
_.extend @, info
|
||||
|
||||
for component_type, info of @available_components
|
||||
unless component_type in available_plugins
|
||||
err = new Error "Plan:#{@name} include unknown Component:#{component_type}"
|
||||
logger.fatal err
|
||||
throw err
|
||||
|
||||
if info.default
|
||||
unless _.isArray info.default
|
||||
info.default = [info.default]
|
||||
|
||||
@@ -1,13 +1,35 @@
|
||||
{_, path, fs, jade, harp} = app.libs
|
||||
{config, logger, i18n} = app
|
||||
{available_plugins} = config.plugin
|
||||
|
||||
pluggable = require '../pluggable'
|
||||
|
||||
module.exports = class Plugin
|
||||
info: null
|
||||
name: null
|
||||
config: null
|
||||
path: null
|
||||
|
||||
@plugins = {}
|
||||
|
||||
@get: (name) ->
|
||||
return @plugins[name]
|
||||
|
||||
@initPlugins: ->
|
||||
for name in available_plugins
|
||||
Plugin.plugins[name] = require path.join __dirname, '../../plugin', name
|
||||
|
||||
constructor: (@info) ->
|
||||
@name = info.name
|
||||
@config = config.plugins[@name] ? {}
|
||||
@path = path.join __dirname, '../plugin', @name
|
||||
@path = path.join __dirname, '../../plugin', @name
|
||||
|
||||
if info.dependencies
|
||||
for dependence in plugin.dependencies
|
||||
unless dependence in available_plugins
|
||||
err = new Error "Plugin:#{@name} is Dependent on Plugin:#{dependence} but not load"
|
||||
logger.fatal err
|
||||
throw err
|
||||
|
||||
for name, payload of info.register_hooks ? {}
|
||||
if payload.register_if
|
||||
@@ -69,7 +91,7 @@ module.exports = class Plugin
|
||||
return t.apply @, _.toArray(arguments)
|
||||
|
||||
render: (name, req, view_data, callback) ->
|
||||
template_path = path.join __dirname, '../plugin', @name, 'view', "#{name}.jade"
|
||||
template_path = path.join __dirname, '../../plugin', @name, 'view', "#{name}.jade"
|
||||
|
||||
locals = _.extend _.clone(req.res.locals), view_data,
|
||||
account: req.account
|
||||
@@ -80,7 +102,7 @@ module.exports = class Plugin
|
||||
callback html
|
||||
|
||||
renderTemplate: (name, view_data, callback) ->
|
||||
template_path = path.join __dirname, '../plugin', @name, 'view', name
|
||||
template_path = path.join __dirname, '../../plugin', @name, 'view', name
|
||||
|
||||
fs.readFile template_path, (err, template_file) ->
|
||||
callback _.template(template_file.toString()) view_data
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{pluggable, utils, config, models} = app
|
||||
{_, async, mongoose, mongooseUniqueValidator} = app.libs
|
||||
{Financial, SecurityLog, Component} = app.models
|
||||
{Plan} = app.interfaces
|
||||
|
||||
Plan = require '../interface/Plan'
|
||||
|
||||
process.nextTick ->
|
||||
{Financial, SecurityLog, Component} = app.models
|
||||
{Plan} = app.interfaces
|
||||
|
||||
Token = mongoose.Schema
|
||||
type:
|
||||
@@ -88,6 +88,7 @@ Account = mongoose.Schema
|
||||
|
||||
pluggable:
|
||||
type: Object
|
||||
default: {}
|
||||
|
||||
resources_limit:
|
||||
type: Object
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{_, ObjectId, mongoose} = app.libs
|
||||
{_, ObjectId, mongoose, async} = app.libs
|
||||
{Account} = app.models
|
||||
|
||||
Component = mongoose.Schema
|
||||
component_type:
|
||||
@@ -43,10 +44,32 @@ Component = mongoose.Schema
|
||||
type: String
|
||||
enum: []
|
||||
|
||||
Component.statics.markAsStatus = (component, status, callback) ->
|
||||
@findByIdAndUpdate component._id,
|
||||
status: status
|
||||
, callback
|
||||
Component.methods.populateComponent = (callback) ->
|
||||
component = @toObject()
|
||||
|
||||
async.parallel
|
||||
account: (callback) ->
|
||||
Account.findById component.account_id, callback
|
||||
|
||||
coworkers: (callback) ->
|
||||
async.each component.coworkers, (coworker, callback) ->
|
||||
Account.findById coworker.account_id, (err, account) ->
|
||||
callback _.extend coworker,
|
||||
account: account
|
||||
, callback
|
||||
|
||||
, (err, result) ->
|
||||
{account, coworkers} = result
|
||||
|
||||
callback _.extend component,
|
||||
account: account
|
||||
coworkers: coworkers
|
||||
component_type: ComponentType.get component.component_type
|
||||
physical_node: Node.get component.physical_node
|
||||
|
||||
Component.methods.markAsStatus = (status, callback) ->
|
||||
@status = status
|
||||
@save callback
|
||||
|
||||
_.extend app.models,
|
||||
Component: mongoose.model 'Component', Component
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{async, path, harp, jade, tmp, fs, _, child_process} = app.libs
|
||||
{i18n, config, logger} = app
|
||||
|
||||
Plugin = require './interface/Plugin'
|
||||
|
||||
pluggable = exports
|
||||
|
||||
pluggable.hooks =
|
||||
@@ -28,8 +30,8 @@ pluggable.hooks =
|
||||
|
||||
billing:
|
||||
# type
|
||||
# widget_generator: function(req, callback(html)),
|
||||
# details_message: function(req, deposit_log, callback(l_details))
|
||||
# widgetGenerator: function(req, callback(html)),
|
||||
# detailsMessage: function(req, deposit_log, callback(l_details))
|
||||
payment_methods: []
|
||||
|
||||
view:
|
||||
@@ -66,18 +68,3 @@ pluggable.selectHookPath = (name) ->
|
||||
|
||||
pluggable.selectHook = (name) ->
|
||||
return pluggable.selectHookPath name
|
||||
|
||||
pluggable.initPlugins = ->
|
||||
plugins_name = config.plugin.available_plugins
|
||||
|
||||
for name in plugins_name
|
||||
plugin = require path.join __dirname, '../plugin', name
|
||||
|
||||
if plugin.dependencies
|
||||
for dependence in plugin.dependencies
|
||||
unless dependence in plugins_name
|
||||
err = new Error "#{name} is Dependent on #{dependence} but not load"
|
||||
logger.fatal err
|
||||
throw err
|
||||
|
||||
exports.plugins[name] = plugin
|
||||
|
||||
3
core/router/component.coffee
Normal file
3
core/router/component.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
{_, express} = app.libs
|
||||
|
||||
module.exports = exports = express.Router()
|
||||
@@ -13,7 +13,7 @@ exports.get '/financials', (req, res) ->
|
||||
async.parallel
|
||||
payment_methods: (callback) ->
|
||||
async.map pluggable.selectHook('billing.payment_methods'), (hook, callback) ->
|
||||
hook.widget_generator req, (html) ->
|
||||
hook.widgetGenerator req, (html) ->
|
||||
callback null, html
|
||||
, callback
|
||||
|
||||
@@ -29,13 +29,13 @@ exports.get '/financials', (req, res) ->
|
||||
async.map deposit_logs, (deposit_log, callback) ->
|
||||
deposit_log = deposit_log.toObject()
|
||||
|
||||
matched_hook = _.find pluggable.selectHook('view.pay.display_payment_details'), (hook) ->
|
||||
return hook?.type == deposit_log.payload.type
|
||||
matched_hook = _.find pluggable.selectHook('billing.payment_methods'), (hook) ->
|
||||
return hook.type == deposit_log.payload.type
|
||||
|
||||
unless matched_hook
|
||||
return callback null, deposit_log
|
||||
|
||||
matched_hook.filter req, deposit_log, (payment_details) ->
|
||||
matched_hook.detailsMessage req, deposit_log, (payment_details) ->
|
||||
deposit_log.payment_details = payment_details
|
||||
callback null, deposit_log
|
||||
|
||||
|
||||
4
library/Mabolo.coffee
Normal file
4
library/Mabolo.coffee
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = class Mabolo
|
||||
constructor: (options) ->
|
||||
|
||||
model: (name) ->
|
||||
@@ -4,7 +4,7 @@
|
||||
# @param callback(address)
|
||||
exports.genAddress = (bitcoin_secret, callback) ->
|
||||
if config.plugins.bitcoin.coinbase_api_key == 'coinbase-simple-api-key'
|
||||
app.deprecate 'Invalid coinbase-simple-api-key'
|
||||
logger.wran plugin: 'bitcoin', new Error 'Invalid coinbase-simple-api-key'
|
||||
return callback()
|
||||
|
||||
request 'https://coinbase.com/api/v1/account/generate_receive_address',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{jade, path} = app.libs
|
||||
{Account} = app.models
|
||||
{pluggable, config, utils} = app
|
||||
{Plugin} = app.classes
|
||||
{Plugin} = app.interfaces
|
||||
|
||||
bitcoin = require './bitcoin'
|
||||
|
||||
@@ -25,16 +25,17 @@ bitcoinPlugin = module.exports = new Plugin
|
||||
|
||||
'billing.payment_methods':
|
||||
type: 'bitcoin'
|
||||
widget_generator: (req, callback) ->
|
||||
|
||||
widgetGenerator: (req, callback) ->
|
||||
bitcoin.getExchangeRate config.billing.currency, (rate) ->
|
||||
bitcoinPlugin.render 'payment_method', req,
|
||||
exchange_rate: rate
|
||||
, callback
|
||||
|
||||
details_message: (req, deposit_log, callback) ->
|
||||
detailsMessage: (req, deposit_log, callback) ->
|
||||
callback bitcoinPlugin.getTranslator(req) 'view.payment_details',
|
||||
order_id: deposit_log.payload.order_id
|
||||
short_order_id: deposit_log.payload.order_id[0 .. 40]
|
||||
short_order_id: deposit_log.payload.order_id[... 40]
|
||||
|
||||
initialize: ->
|
||||
app.express.post '/bitcoin/coinbase_callback', (req, res) ->
|
||||
@@ -42,10 +43,10 @@ bitcoinPlugin = module.exports = new Plugin
|
||||
'pluggable.bitcoin.bitcoin_deposit_address': req.body.address
|
||||
, (err, account) ->
|
||||
unless account
|
||||
return res.send 400, 'Invalid Address'
|
||||
return res.status(400).send 'Invalid Address'
|
||||
|
||||
unless req.query.secret == account.pluggable.bitcoin.bitcoin_secret
|
||||
return res.send 400, 'Invalid Secret'
|
||||
return res.status(400).send 'Invalid Secret'
|
||||
|
||||
bitcoin.getExchangeRate config.billing.currency, (rate) ->
|
||||
amount = req.body.amount / rate
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"view": {
|
||||
"payment_tips": "You can transfer directly to this address. system will automatically recharge for you after first confirmed. The minimum payment amount: 0.0005 BTC.",
|
||||
"exchange_rate_tips": "Real-time Exchange Rates: 10 CNY = __rate10__ BTC",
|
||||
"payment_details": "Bitcoin Payment <a href='https://blockchain.info/tx/__order_id__'>__short_order_id__</a>"
|
||||
"payment_details": "Bitcoin Payment <a href='https://blockchain.info/tx/__order_id__'>__short_order_id__</a>",
|
||||
"no_address": "No Address"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"view": {
|
||||
"payment_tips": "你可以直接向该地址发送比特币。在经过一次确认后,系统会实时地,自动为你折算充值金额,最小支付金额为 0.0005 BTC.",
|
||||
"exchange_rate_tips": "实时汇率:10 CNY = __rate10__ BTC",
|
||||
"payment_details": "比特币支付 <a href='https://blockchain.info/tx/__order_id__'>__short_order_id__</a>"
|
||||
"payment_details": "比特币支付 <a href='https://blockchain.info/tx/__order_id__'>__short_order_id__</a>",
|
||||
"no_address": "暂无地址"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,7 @@ div
|
||||
h2= t('')
|
||||
p= t('view.payment_tips')
|
||||
p= t('view.exchange_rate_tips', {rate10: (exchange_rate * 10).toFixed(4)})
|
||||
pre= account.pluggable.bitcoin.bitcoin_deposit_address
|
||||
if account.pluggable.bitcoin
|
||||
pre= account.pluggable.bitcoin.bitcoin_deposit_address
|
||||
else
|
||||
pre= t('view.no_address')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{jade, path, fs} = app.libs
|
||||
{path, fs} = app.libs
|
||||
{pluggable, config} = app
|
||||
{Plugin} = app.classes
|
||||
{Plugin} = app.interfaces
|
||||
|
||||
rpvhostPlugin = module.exports = new Plugin
|
||||
name: 'rpvhost'
|
||||
@@ -21,10 +21,11 @@ rpvhostPlugin = module.exports = new Plugin
|
||||
|
||||
'billing.payment_methods':
|
||||
type: 'taobao'
|
||||
widget_generator: (req, callback) ->
|
||||
|
||||
widgetGenerator: (req, callback) ->
|
||||
rpvhostPlugin.render 'payment_method', req, {}, callback
|
||||
|
||||
details_message: (req, deposit_log, callback) ->
|
||||
detailsMessage: (req, deposit_log, callback) ->
|
||||
callback rpvhostPlugin.getTranslator(req) 'view.payment_details',
|
||||
order_id: deposit_log.payload.order_id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user