1 package FS::ClientAPI_XMLRPC;
5 FS::ClientAPI_XMLRPC - Freeside XMLRPC accessible self-service API, on the backend
9 This module implements the self-service API offered by xmlrpc.cgi and friends,
10 but on a backend machine.
14 Use this API to implement your own client "self-service" module vi XMLRPC.
16 Each routine described in L<FS::SelfService> is available vi XMLRPC as the
17 method FS.SelfService.XMLRPC.B<method>. All values are passed to the
18 selfservice-server in a struct of strings. The return values are in a
19 struct as strings, arrays, or structs as appropriate for the values
20 described in L<FS::SelfService>.
26 L<FS::SelfService::XMLRPC>, L<FS::SelfService>
32 use vars qw($DEBUG $AUTOLOAD);
34 use FS::XMLRPC_Lite; #XMLRPC::Lite, for XMLRPC::Data
38 $FS::ClientAPI::DEBUG = $DEBUG;
40 #false laziness w/FS::SelfService/XMLRPC.pm, same problem as below but worse
41 our %typefix_skin_info = (
43 'title_left_image' => 'base64',
44 'title_right_image' => 'base64',
45 'menu_top_image' => 'base64',
46 'menu_body_image' => 'base64',
47 'menu_bottom_image' => 'base64',
50 'invoice_pdf' => { 'invoice_pdf' => 'base64', },
51 'legacy_invoice_pdf' => { 'invoice_pdf' => 'base64', },
52 'skin_info' => \%typefix_skin_info,
53 'payment_only_skin_info' => \%typefix_skin_info,
54 'login_info' => \%typefix_skin_info,
55 'logout' => \%typefix_skin_info,
56 'access_info' => \%typefix_skin_info,
57 'reset_passwd' => \%typefix_skin_info,
58 'check_reset_passwd' => \%typefix_skin_info,
59 'process_reset_passwd' => \%typefix_skin_info,
60 'invoice_logo' => { 'logo' => 'base64', },
61 'login_banner_image' => { 'image' => 'base64', },
62 'quotation_print' => { 'document' => 'base64' },
67 $call =~ s/^FS::(SelfService::|ClientAPI_)XMLRPC:://;
69 warn "FS::ClientAPI_XMLRPC::AUTOLOAD $call\n" if $DEBUG;
71 my $autoload = &ss2clientapi;
73 if (exists($autoload->{$call})) {
75 shift; #discard package name;
78 #$call = "FS::SelfService::$call";
81 #FS::ClientAPI->dispatch($autoload->{$call}, @_);
84 #XXX doesn't deep-fix multi-level data structs, but at least doesn't mangle
86 $hash{$_} = decode(utf8=>$hash{$_})
87 foreach grep !ref($hash{$_}), keys %hash;
89 my $return = FS::ClientAPI->dispatch($autoload->{$call}, \%hash );
91 if ( exists($typefix{$call}) ) {
92 my $typefix = $typefix{$call};
93 foreach my $field ( grep exists($return->{$_}), keys %$typefix ) {
94 my $type = $typefix->{$field};
95 $return->{$field} = XMLRPC::Data->value($return->{$field})
103 die "No such procedure: $call";
107 #terrible false laziness w/SelfService.pm
108 # - fix at build time, by including some file in both selfserv and backend libs?
109 # - or fix at runtime, by having selfservice client ask server for the list?
112 'passwd' => 'passwd/passwd',
113 'chfn' => 'passwd/passwd',
114 'chsh' => 'passwd/passwd',
115 'login_info' => 'MyAccount/login_info',
116 'login_banner_image' => 'MyAccount/login_banner_image',
117 'login' => 'MyAccount/login',
118 'logout' => 'MyAccount/logout',
119 'switch_acct' => 'MyAccount/switch_acct',
120 'switch_cust' => 'MyAccount/switch_cust',
121 'customer_info' => 'MyAccount/customer_info',
122 'customer_info_short' => 'MyAccount/customer_info_short',
123 'customer_recurring' => 'MyAccount/customer_recurring',
125 'contact_passwd' => 'MyAccount/contact/contact_passwd',
126 'list_contacts' => 'MyAccount/contact/list_contacts',
127 'edit_contact' => 'MyAccount/contact/edit_contact',
128 'delete_contact' => 'MyAccount/contact/delete_contact',
129 'new_contact' => 'MyAccount/contact/new_contact',
131 'billing_history' => 'MyAccount/billing_history',
132 'edit_info' => 'MyAccount/edit_info', #add to ss cgi!
133 'invoice' => 'MyAccount/invoice',
134 'invoice_pdf' => 'MyAccount/invoice_pdf',
135 'legacy_invoice' => 'MyAccount/legacy_invoice',
136 'legacy_invoice_pdf' => 'MyAccount/legacy_invoice_pdf',
137 'invoice_logo' => 'MyAccount/invoice_logo',
138 'list_invoices' => 'MyAccount/list_invoices', #?
139 'list_payments' => 'MyAccount/list_payments',
140 'payment_receipt' => 'MyAccount/payment_receipt',
141 'list_payby' => 'MyAccount/list_payby',
142 'insert_payby' => 'MyAccount/insert_payby',
143 'update_payby' => 'MyAccount/update_payby',
144 'delete_payby' => 'MyAccount/delete_payby',
145 'cancel' => 'MyAccount/cancel', #add to ss cgi!
146 'payment_info' => 'MyAccount/payment_info',
147 'payment_info_renew_info' => 'MyAccount/payment_info_renew_info',
148 'process_payment' => 'MyAccount/process_payment',
149 'store_payment' => 'MyAccount/store_payment',
150 'process_stored_payment' => 'MyAccount/process_stored_payment',
151 'process_payment_order_pkg' => 'MyAccount/process_payment_order_pkg',
152 'process_payment_change_pkg' => 'MyAccount/process_payment_change_pkg',
153 'process_payment_order_renew' => 'MyAccount/process_payment_order_renew',
154 'process_prepay' => 'MyAccount/process_prepay',
155 'start_thirdparty' => 'MyAccount/start_thirdparty',
156 'finish_thirdparty' => 'MyAccount/finish_thirdparty',
157 'realtime_collect' => 'MyAccount/realtime_collect',
158 'list_pkgs' => 'MyAccount/list_pkgs', #add to ss (added?)
159 'pkg_info' => 'MyAccount/pkg_info',
160 'list_svcs' => 'MyAccount/list_svcs', #add to ss (added?)
161 'list_svc_usage' => 'MyAccount/list_svc_usage',
162 'svc_status_html' => 'MyAccount/svc_status_html',
163 'svc_status_hash' => 'MyAccount/svc_status_hash',
164 'set_svc_status_hash' => 'MyAccount/set_svc_status_hash',
165 'set_svc_status_listadd' => 'MyAccount/set_svc_status_listadd',
166 'set_svc_status_listdel' => 'MyAccount/set_svc_status_listdel',
167 'set_svc_status_vacationadd'=> 'MyAccount/set_svc_status_vacationadd',
168 'set_svc_status_vacationdel'=> 'MyAccount/set_svc_status_vacationdel',
169 'acct_forward_info' => 'MyAccount/acct_forward_info',
170 'process_acct_forward' => 'MyAccount/process_acct_forward',
171 'list_dsl_devices' => 'MyAccount/list_dsl_devices',
172 'add_dsl_device' => 'MyAccount/add_dsl_device',
173 'delete_dsl_device' => 'MyAccount/delete_dsl_device',
174 'port_graph' => 'MyAccount/port_graph',
175 'list_cdr_usage' => 'MyAccount/list_cdr_usage',
176 'list_support_usage' => 'MyAccount/list_support_usage',
177 'order_pkg' => 'MyAccount/order_pkg', #add to ss cgi!
178 'change_pkg' => 'MyAccount/change_pkg',
179 'order_recharge' => 'MyAccount/order_recharge',
180 'renew_info' => 'MyAccount/renew_info',
181 'order_renew' => 'MyAccount/order_renew',
182 'cancel_pkg' => 'MyAccount/cancel_pkg', #add to ss cgi!
183 'suspend_pkg' => 'MyAccount/suspend_pkg', #add to ss cgi!
184 'charge' => 'MyAccount/charge', #?
185 'part_svc_info' => 'MyAccount/part_svc_info',
186 'provision_acct' => 'MyAccount/provision_acct',
187 'provision_phone' => 'MyAccount/provision_phone',
188 'provision_pbx' => 'MyAccount/provision_pbx',
189 'provision_external' => 'MyAccount/provision_external',
190 'unprovision_svc' => 'MyAccount/unprovision_svc',
191 'myaccount_passwd' => 'MyAccount/myaccount_passwd',
192 'reset_passwd' => 'MyAccount/reset_passwd',
193 'check_reset_passwd' => 'MyAccount/check_reset_passwd',
194 'process_reset_passwd' => 'MyAccount/process_reset_passwd',
195 'validate_passwd' => 'MyAccount/validate_passwd',
196 'list_tickets' => 'MyAccount/list_tickets',
197 'create_ticket' => 'MyAccount/create_ticket',
198 'get_ticket' => 'MyAccount/get_ticket',
199 'adjust_ticket_priority' => 'MyAccount/adjust_ticket_priority',
200 'did_report' => 'MyAccount/did_report',
201 'signup_info' => 'Signup/signup_info',
202 'skin_info' => 'MyAccount/skin_info',
203 'access_info' => 'MyAccount/access_info',
204 'domain_select_hash' => 'Signup/domain_select_hash', # expose?
205 'new_customer' => 'Signup/new_customer',
206 'new_customer_minimal' => 'Signup/new_customer_minimal',
207 'capture_payment' => 'Signup/capture_payment',
208 'clear_signup_cache' => 'Signup/clear_cache',
209 'new_prospect' => 'Signup/new_prospect',
210 'new_agent' => 'Agent/new_agent',
211 'agent_login' => 'Agent/agent_login',
212 'agent_logout' => 'Agent/agent_logout',
213 'agent_info' => 'Agent/agent_info',
214 'agent_list_customers' => 'Agent/agent_list_customers',
215 'check_username' => 'Agent/check_username',
216 'suspend_username' => 'Agent/suspend_username',
217 'unsuspend_username' => 'Agent/unsuspend_username',
218 'mason_comp' => 'MasonComponent/mason_comp',
219 'payment_only_mason_comp' => 'MasonComponent/payment_only_mason_comp',
220 'call_time' => 'PrepaidPhone/call_time',
221 'call_time_nanpa' => 'PrepaidPhone/call_time_nanpa',
222 'phonenum_balance' => 'PrepaidPhone/phonenum_balance',
224 'list_quotations' => 'MyAccount/quotation/list_quotations',
225 'quotation_new' => 'MyAccount/quotation/quotation_new',
226 'quotation_delete' => 'MyAccount/quotation/quotation_delete',
227 'quotation_info' => 'MyAccount/quotation/quotation_info',
228 'quotation_print' => 'MyAccount/quotation/quotation_print',
229 'quotation_add_pkg' => 'MyAccount/quotation/quotation_add_pkg',
230 'quotation_remove_pkg' => 'MyAccount/quotation/quotation_remove_pkg',
231 'quotation_order' => 'MyAccount/quotation/quotation_order',
232 'ip_login' => 'PaymentOnly/ip_login',
233 'ip_logout' => 'PaymentOnly/ip_logout',
234 'get_mac_address' => 'PaymentOnly/get_mac_address',
235 'payment_only_skin_info' => 'PaymentOnly/payment_only_skin_info',
236 'payment_only_payment_info' => 'PaymentOnly/payment_only_payment_info',
237 'payment_only_process_payment' => 'PaymentOnly/payment_only_process_payment',
239 'freesideinc_service' => 'Freeside/freesideinc_service',